[
  {
    "path": ".eslintignore",
    "content": "node_modules\npackage.json\n*.json\nlib/utils/requireModule.js\nlib/reporter/reporters/html\ndist\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"root\": true,\n  \"extends\": [\n    \"eslint:recommended\"\n  ],\n  \"parserOptions\": {\n    \"ecmaVersion\": 13,\n    \"sourceType\": \"module\",\n    \"ecmaFeatures\": {\n      \"jsx\": false\n    }\n  },\n  \"env\": {\n    \"mocha\": true,\n    \"node\": true\n  },\n  \"overrides\": [\n    {\n      \"files\": [\n        \"**/*.ts\"\n      ],\n      \"excludedFiles\": [\n        \"test/**/*.ts\"\n      ],\n      \"extends\": [\n        \"eslint:recommended\",\n        \"plugin:@typescript-eslint/eslint-recommended\",\n        \"plugin:@typescript-eslint/recommended\"\n      ],\n      \"parser\": \"@typescript-eslint/parser\",\n      \"plugins\": [\n        \"@typescript-eslint\"\n      ],\n      \"parserOptions\": {\n        \"ecmaVersion\": 2020,\n        \"sourceType\": \"module\",\n        \"ecmaFeatures\": {\n          \"jsx\": false\n        },\n        \"project\": \"./tsconfig.json\"\n      }\n    }\n  ],\n  \"rules\": {\n    \"eqeqeq\": [\n      \"error\",\n      \"smart\"\n    ],\n    \"no-extra-boolean-cast\": 0,\n    \"quotes\": [\n      \"error\",\n      \"single\"\n    ],\n    \"curly\": [\n      \"error\",\n      \"all\"\n    ],\n    \"no-console\": [\n      \"error\",\n      {\n        \"allow\": [\n          \"error\"\n        ]\n      }\n    ],\n    \"no-debugger\": 1,\n    \"semi\": [\n      \"error\",\n      \"always\",\n      {\n        \"omitLastInOneLineBlock\": true\n      }\n    ],\n    \"no-trailing-spaces\": 1,\n    \"no-else-return\": 2,\n    \"no-extra-bind\": 0,\n    \"no-implicit-coercion\": 0,\n    \"no-useless-call\": 0,\n    \"no-return-assign\": 0,\n    \"eol-last\": 1,\n    \"no-unused-vars\": 0,\n    \"no-extra-semi\": 0,\n    \"comma-dangle\": 2,\n    \"no-underscore-dangle\": 0,\n    \"no-lone-blocks\": 0,\n    \"array-bracket-spacing\": 2,\n    \"object-curly-spacing\": 2,\n    \"brace-style\": [\n      2,\n      \"1tbs\",\n      {\n        \"allowSingleLine\": true\n      }\n    ],\n    \"comma-spacing\": 2,\n    \"comma-style\": 2,\n    \"key-spacing\": 2,\n    \"one-var\": [\n      \"error\",\n      \"never\"\n    ],\n    \"semi-style\": [\n      \"error\",\n      \"last\"\n    ],\n    \"space-in-parens\": [\n      \"error\",\n      \"never\"\n    ],\n    \"keyword-spacing\": [\n      2,\n      {\n        \"before\": true,\n        \"after\": true\n      }\n    ],\n    \"space-infix-ops\": 1,\n    \"padding-line-between-statements\": [\n      \"error\",\n      {\n        \"blankLine\": \"always\",\n        \"prev\": \"*\",\n        \"next\": \"return\"\n      }\n    ],\n    \"indent\": [\n      \"error\",\n      2,\n      {\n        \"SwitchCase\": 1\n      }\n    ],\n    \"prefer-const\": [\n      \"warn\"\n    ]\n  },\n  \"globals\": {\n    \"Promise\": true,\n    \"Proxy\": true,\n    \"Set\": true,\n    \"Reflect\": true,\n    \"element\": \"readonly\",\n    \"by\": \"readonly\",\n    \"expect\": \"readonly\",\n    \"browser\": \"readonly\",\n    \"app\": \"readonly\",\n    \"Key\": \"readonly\"\n  }\n}\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "open_collective: nightwatch\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: \"Bug Report\"\ndescription: \"File a bug report to help us improve Nightwatch.\"\nbody:\n  - type: \"markdown\"\n    attributes:\n      value: |\n        Thanks in advance for your contribution. Before submitting a new issue, try searching for a similar one here: https://github.com/nightwatchjs/nightwatch/search?type=Issues.\n  - type: \"textarea\"\n    id: \"description\"\n    attributes:\n      label: \"Description of the bug/issue\"\n      description: \"A brief description of the issue, how to reproduce it, and the expected behavior.\"\n      placeholder: |\n        When I ____, I expected ____ to happen but ____ happened instead.\n    validations:\n      required: true\n  - type: \"textarea\"\n    id: \"steps\"\n    attributes:\n      label: \"Steps to reproduce\"\n      description: |\n        Explain how to cause the issue in the provided reproduction.\n      value: |\n        1. Go to '...'\n        2. Click on '...'\n        3. Scroll down to '...'\n        4. See error\n  - type: textarea\n    id: \"sample-test\"\n    attributes:\n      label: \"Sample test\"\n      description:\n        Include a sample test that reproduces the problem you're experiencing. If possible, the test should be against a public URL.\n\n        Please add the test and other info inline, not as attachments or screenshots.\n      placeholder: |\n        // Please add the sample test here\n\n        module.exports = {\n          sampleTest: function() {\n            browser\n              .navigateTo('<URL here>')\n              .click('<selector>')\n              .end();\n          }\n        }\n      render: node\n  - type: textarea\n    id: \"run-with-command\"\n    attributes:\n      label: \"Command to run\"\n      description: \"Include the command used to run the test.\"\n      placeholder: |\n        nightwatch test/sampleTest.js --your-other-arguments-here\n      render: bash\n  - type: textarea\n    id: \"verbose-output\"\n    attributes:\n      label: \"Verbose Output\"\n      description: |\n        \"Extended nightwatch command logging during the session. \n        Please use nightwatch --verbose and paste the output here\"\n      placeholder: |\n        [Sample Test] Test Suite\n        ────────────────────────────────────────────────────────\n        ⠋ Starting ChromeDriver on port 9515...\n          Request POST /session\n          {\n            desiredCapabilities: {\n              browserName: 'chrome',\n              'goog:chromeOptions': { w3c: true, args: [] },\n              name: 'Sample Test'\n            },\n            capabilities: {\n              alwaysMatch: {\n                browserName: 'chrome',\n                'goog:chromeOptions': { w3c: true, args: [] }\n              }\n            }\n      render: fundamental\n  - type: textarea\n    id: \"configuration\"\n    attributes:\n      label: \"Nightwatch Configuration\"\n      description: \"Add your nightwatch.json or nightwatch.conf.js here; Make sure to leave out any sensitive details.\"\n      placeholder: |\n        module.exports = {\n          src_folders: [],\n          page_objects_path: [],\n          custom_commands_path: [],\n          custom_assertions_path: '',\n          plugins: [],\n          globals_path: '',\n          webdriver: {},\n          test_settings: {}\n        }\n      render: node\n  - type: \"markdown\"\n    attributes:\n      value: |\n        ## Your Environment\n        Include the relevant details related to your environment.\n  - type: \"input\"\n    id: \"nightwatch-version\"\n    attributes:\n      label: \"Nightwatch.js Version\"\n      description: \"The version of Nightwatch you are using. Run: nightwatch --version\"\n      placeholder: \"2.3.0\"\n    validations:\n      required: true\n  - type: \"input\"\n    id: \"node-version\"\n    attributes:\n      label: \"Node Version\"\n      description: \"The version of Node you are using.\"\n      placeholder: \"14.0.0\"\n  - type: \"input\"\n    id: \"browser\"\n    attributes:\n      label: \"Browser\"\n      description: \"The browser(s) this issue occurred with.\"\n      placeholder: \"Firefox 102.0.1; Chrome 104.0.0\"\n  - type: \"input\"\n    id: \"operating-system\"\n    attributes:\n      label: \"Operating System\"\n      description: \"The operating system(s) this issue occurred with.\"\n      placeholder: \"MacOs Monterey 12.5\"\n  - type: \"textarea\"\n    id: \"additional-information\"\n    attributes:\n      label: \"Additional Information\"\n      description: |\n        Use this section to provide any additional information you might have\n        like screenshots, notes, or links to ideas.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: true\ncontact_links:\n  - name: Ask a question\n    url: https://github.com/nightwatchjs/nightwatch/discussions\n    about: Ask questions and discuss topics with other community members\n  - name: Documentation Request\n    url: https://github.com/nightwatchjs/nightwatch-docs/issues/new\n    about: Request for documentation to be added/altered\n  - name: Chat with other community members. Ask support questions, discuss news and feature requests.\n    url: https://discord.gg/x5RuXc6Z\n    about: The official Nightwatchjs Discord community\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.yml",
    "content": "name: \"Feature Request\"\ndescription: \"Request a feature or enhancement for Nightwatch\"\nlabels: [\"enhancement\"]\nbody:\n  - type: \"markdown\"\n    attributes:\n      value: |\n        Thanks in advance for your contribution. Before requesting a new feature, try searching for a similar issue here: https://github.com/nightwatchjs/nightwatch/search?type=Issues.\n  - type: \"textarea\"\n    id: \"description\"\n    attributes:\n      label: \"Description\"\n      description: \"Please describe your request in one or two sentences.\"\n    validations:\n      required: true\n  - type: \"textarea\"\n    id: \"proposed-solution\"\n    attributes:\n      label: \"Suggested solution\"\n      description: |\n        Please provide code snippets, gists, or links to the ideal\n        design or API.\n  - type: \"textarea\"\n    id: \"alternatives\"\n    attributes:\n      label: \"Alternatives / Workarounds\"\n      description: |\n        What alternative solutions have you considered before making this\n        request?\n  - type: \"textarea\"\n    id: \"additional-information\"\n    attributes:\n      label: \"Additional Information\"\n      description: |\n        What resources (links, screenshots, etc.) do you have to assist this\n        effort?\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Thanks in advance for your contribution. Please follow the below steps in submitting a pull request, as it will help us with reviewing it quicker.\n\n- [ ] Before marking your PR for review, please test and verify your changes by making appropriate modifications to any of the Nightwatch example tests (present in `examples/tests` directory of the project) and running them. `ecosia.js` and `duckDuckGo.js` are good examples to work with.\n- [ ] Create a new branch from master (e.g. `features/my-new-feature` or `issue/123-my-bugfix`);\n- [ ] If you're fixing a bug also create an issue if one doesn't exist yet;\n- [ ] If it's a new feature explain why do you think it's necessary. Please check with the maintainers beforehand to make sure it is something that we will accept. Usually we only accept new features if we feel that they will benefit the entire community;\n- [ ] Please avoid sending PRs which contain drastic or low level changes. If you are certain that the changes are needed, please discuss them beforehand and indicate what the impact will be;\n- [ ] If your change is based on existing functionality please consider refactoring first. Pull requests that duplicate code will most likely be ignored;\n- [ ] Do not include changes that are not related to the issue at hand;\n- [ ] Follow the same coding style with regards to spaces, semicolons, variable naming etc.;\n- [ ] Always add unit tests - PRs without tests are most of the times ignored.\n"
  },
  {
    "path": ".github/label-commenter-config.yml",
    "content": "  # Configuration for Label Commenter - https://github.com/peaceiris/actions-label-commenter\nlabels:\n  - name: needs-triaging\n    labeled:\n      issue:\n        body: |\n          @{{ issue.user.login }}, thank you for creating this issue. We will troubleshoot it as soon as we can.\n\n          ---\n          <details>\n            <summary>Info for maintainers</summary>\n            <div>\n              <br>\n              <p>\n                Triage this issue by using labels.\n              </p>\n              <p>\n                If information is missing, add a helpful comment and add the <code>I-issue-template</code> label.\n              </p>\n              <p>\n                Thank you!\n              </p>\n            </div>\n          </details>\n  - name: I-issue-template\n    labeled:\n      issue:\n        body: |\n          Hi, @{{ issue.user.login }}.\n          Please follow the issue template, we need more information to reproduce the issue.\n\n          Either a complete code snippet (if more than one file is needed, provide a GitHub repo and instructions to run the code), the specific versions used, or a more detailed description to help us understand the issue.\n\n          Reply to this issue when all information is provided, thank you.\n \n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 90\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 7\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - META\n  - pinned\n  - enhancement\n# Label to use when marking an issue as stale\nstaleLabel: stale\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  This issue has been automatically marked as stale because it has not had any recent activity. \n  \n  If possible, please retry using the latest Nightwatch version and update the issue with any relevant details.\n  If no further activity occurs, it will be closed. Thank you for your contribution.\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: false\n"
  },
  {
    "path": ".github/workflows/build-node.yaml",
    "content": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node\n# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions\n\nname: tests\n\non:\n  push:\n    branches: [ main]\n  pull_request:\n    branches: [ main]\n\njobs:\n  linux:\n\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        node-version: [18.x, 20.x, 22.x, 24.x]\n        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/\n\n    steps:\n    - uses: actions/checkout@v2\n    - name: Use Node.js ${{ matrix.node-version }}\n      uses: actions/setup-node@v2\n      with:\n        node-version: ${{ matrix.node-version }}\n    - run: npm ci\n    - run: npm run eslint\n    - run: npm test\n\n  windows:\n    runs-on: windows-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        node-version: [18.x, 20.x, 22.x, 24.x]\n    steps:\n    - uses: actions/checkout@v2\n    - name: Use Node.js ${{ matrix.node-version }}\n      uses: actions/setup-node@v2\n      with:\n        node-version: ${{ matrix.node-version }}\n    - run: npm ci\n    - run: npm run eslint\n    - run: npm test\n"
  },
  {
    "path": ".github/workflows/component-tests.yaml",
    "content": "name: component-tests\n\non:\n  push:\n    branches: [ main]\n  pull_request:\n    branches: [ main]\n\njobs:\n  linux:\n\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version: [18.x]\n    steps:\n      - uses: actions/checkout@v2\n      - name: Use Node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v2\n        with:\n          node-version: ${{ matrix.node-version }}\n      - run: npm ci\n#       - run: npm i @nightwatch/react @nightwatch/vue @testing-library/dom vite-plugin-nightwatch vue react react-dom\n#       - run: npm run component-tests\n"
  },
  {
    "path": ".github/workflows/coverage.yml",
    "content": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node\n# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions\n\nname: Coverage Job\n\non:\n  push:\n    branches: [  ]\n  pull_request:\n    branches: [  ]\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version: [18.x]\n        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/\n\n    steps:\n    - uses: actions/checkout@v2\n    - name: Use Node.js ${{ matrix.node-version }}\n      uses: actions/setup-node@v2\n      with:\n        node-version: ${{ matrix.node-version }}\n    - run: npm ci\n    - run: npm run eslint\n    - run: npm run mocha-coverage\n    - run: npm run coverage\n\n    - name: Upload coverage to Codecov\n      uses: codecov/codecov-action@v1\n      with:\n        token: ${{ secrets.CODECOV_ACCESS_TOKEN }}\n        files: ./coverage/mocha_coverage.lcov\n        flags: unittests\n        name: codecov-umbrella\n        fail_ci_if_error: true\n        path_to_write_report: codecov_report.txt\n        verbose: false\n"
  },
  {
    "path": ".github/workflows/label-commenter.yml",
    "content": "# Configuration for Label Commenter - https://github.com/peaceiris/actions-label-commenter\nname: Label Commenter\n\non:\n  issues:\n    types: [ labeled ]\n\npermissions:\n  contents: read\n  issues: write\n\njobs:\n  comment:\n    runs-on: ubuntu-20.04\n    steps:\n      - uses: actions/checkout@v2\n      - name: Label Commenter\n        uses: peaceiris/actions-label-commenter@v1\n"
  },
  {
    "path": ".github/workflows/missing-types-comment.yml",
    "content": "name: Add comment for missing types\n\non:\n  workflow_run:\n    workflows: [\"Check missing types\"]\n    types:\n      - completed\n\njobs:\n  add_comment:\n    runs-on: ubuntu-latest\n    if: >\n      github.event.workflow_run.event == 'pull_request' &&\n      github.event.workflow_run.conclusion == 'success'\n    steps:\n      - name: 'Download artifact'\n        uses: actions/github-script@v6\n        with:\n          script: |\n            var artifacts = await github.rest.actions.listWorkflowRunArtifacts({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              run_id: ${{github.event.workflow_run.id }},\n            });\n            var matchArtifact = artifacts.data.artifacts.filter((artifact) => {\n              return artifact.name == \"pr\"\n            })[0];\n            var download = await github.rest.actions.downloadArtifact({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              artifact_id: matchArtifact.id,\n              archive_format: 'zip',\n            });\n            var fs = require('fs');\n            fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data));\n\n      - name: 'Read artifact'\n        id: modified-files\n        run: |\n          unzip pr.zip\n          cat files_changed\n          echo \"modified=$(cat files_changed)\" >> \"$GITHUB_OUTPUT\"\n\n      - name: Comment on PR\n        if: steps.modified-files.outputs.modified == ''\n        id: comment-on-pr\n        uses: actions/github-script@v6\n        with:\n          script: |\n            const fs = require('fs');\n            const issue_number = Number(fs.readFileSync('./NR'));\n            const comment = `\n            ## Status\n            * ❌ No modified files found in the **types** directory.\n            Please make sure to include types for any changes you have made. Thank you!.`;\n            const pullRequest = await github.rest.pulls.get({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              pull_number: issue_number\n            });\n            const comments = await github.rest.issues.listComments({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              issue_number: issue_number\n            });\n            const existingComment = comments.data.find(comment => comment.user.login === 'github-actions[bot]' && comment.body.includes('No modified files found in the **types** director'));\n            if (existingComment) {\n              console.log('Comment already exists');\n            } else {\n              await github.rest.issues.createComment({\n                owner: context.repo.owner,\n                repo: context.repo.repo,\n                issue_number: issue_number,\n                body: comment\n              });\n            }\n\n      - name: Edit comment on PR\n        if: steps.modified-files.outputs.modified != ''\n        uses: actions/github-script@v6\n        with:\n          script: |\n            const fs = require('fs');\n            const issue_number = Number(fs.readFileSync('./NR'));\n            const comment = `\n            ## Status\n            * :white_check_mark: Type files updated!`;\n            const comments = await github.rest.issues.listComments({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              issue_number: issue_number\n            });\n            const existingComment = comments.data.find(comment => comment.user.login === 'github-actions[bot]' && comment.body.includes('No modified files found in the **types** director'));\n            if (existingComment) {\n              await github.rest.issues.updateComment({\n                owner: context.repo.owner,\n                repo: context.repo.repo,\n                comment_id: existingComment.id,\n                body: comment\n              });\n            }\n"
  },
  {
    "path": ".github/workflows/missing-types.yml",
    "content": "name: Check missing types\n\non: pull_request\n\njobs:\n  detect-modified-files:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v3\n        with:\n          fetch-depth: 0\n\n      - name: Get modified files\n        id: modified-files\n        run: |\n          echo $(git diff --name-only origin/$GITHUB_BASE_REF $GITHUB_SHA types/ | tr '\\n' ',')\n          mkdir -p ./pr\n          echo $(git diff --name-only origin/$GITHUB_BASE_REF $GITHUB_SHA types/ | tr '\\n' ',') > ./pr/files_changed\n          echo ${{ github.event.number }} > ./pr/NR\n\n      - uses: actions/upload-artifact@v4\n        with:\n          name: pr\n          path: pr/\n"
  },
  {
    "path": ".github/workflows/nightly.yml",
    "content": "name: Nightly\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: Nightly version\n        required: false\n        type: string\n        default: ''\n      ref:\n        description: Branch, tag, or SHA to release\n        required: false\n        type: string\n        default: ''\n\njobs:\n  nightly:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n        with:\n          ref: ${{ inputs.ref }}\n      - name: Setup Node\n        uses: actions/setup-node@v3\n        with:\n          node-version: '18.x'\n      - name: Install dependencies\n        run: npm install\n      - name: Build Nightwatch\n        run: npm run build\n      - name: Create publishable package 📦\n        run: npm pack\n      - name: Release Nightly\n        uses: marvinpinto/action-automatic-releases@latest\n        with:\n          repo_token: \"${{ secrets.GITHUB_TOKEN }}\"\n          automatic_release_tag: \"nightly-${{ inputs.version }}\"\n          title: \"Nightly ${{ inputs.version }}\"\n          prerelease: true\n          files: '*.tgz'\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "name: Publish to NPM\non:\n  push:\n    tags:\n      - vv* # to enable this action, change this tag back to v*\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n      - name: Setup Node\n        uses: actions/setup-node@v4\n        with:\n          node-version: '20.x'\n          registry-url: 'https://registry.npmjs.org'\n      - name: Install dependencies\n        run: npm install\n      - name: Publish package on NPM 📦\n        run: npm publish\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/type-declaration-tests.yml",
    "content": "name: Type Declaration Tests\n\non:\n  push:\n    branches: [main, feat/types-test]\n  pull_request:\n    branches: [main]\n\njobs:\n  linux:\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version: [18.x]\n        typescript-version: [3.9, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5.0]\n    steps:\n      - uses: actions/checkout@v2\n      - name: Use Node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v2\n        with:\n          node-version: ${{ matrix.node-version }}\n      - name: Install TypeScript\n        run: npm install -g typescript@${{ matrix.typescript-version }}\n      - name: Install Dependencies\n        run: npm ci\n      - run: npm run test:types\n"
  },
  {
    "path": ".gitignore",
    "content": ".project\n.DS_Store\n*.vim\n*.idea\n*.vscode\n*.log\n*.env\n/nightwatch.json\n/nightwatch.conf.js\nnode_modules\ndist\nnpm-debug.log\nlib-cov\ncoverage.html\nselenium-debug.log\nphantomjsdriver.log\ntests_output\n*~\n\\#*\n\\.#*\noutput\n/test/hooks_output\n/bin/geckodriver*\n/coverage/\n/.nyc_output/\nscreenshot.png\n/sample\n/screens\n/logs\nhtml-report/\ntest-results.xml\nchromedriver-mobile/\n*.sw[po]\nsnapshot.html\n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\nnpx lint-staged\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, gender, gender identity and expression, sex characteristics, disability, ethnicity, level of experience, education, socio-economic status, nationality, personal appearance, body size, race, religion (or lack thereof), or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n* Using welcoming and inclusive language - please read the [inclusive language guidance](https://www.uua.org/lgbtq/welcoming/ways/200008.shtml) from the UUA\n* Being respectful of differing viewpoints and experiences\n* Showing empathy towards other community members\n* Gracefully accepting constructive criticism\n* Exercising consideration and respect in your speech and actions\n* Attempting collaboration before conflict or criticism\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or advances\n* Trolling, spamming, intentionally disrupting conversations, making insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing or threatening to publish others' private information, such as a physical or electronic address, without explicit permission\n* Advocating for, or encouraging, any of the above behavior\n* Other conduct which could reasonably be considered inappropriate in a professional setting\n\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@pineview.io. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html. \n\nIt's inspired among other things by:\n\n- [Citizen Code of Conduct](http://citizencodeofconduct.org/)\n- [Appium](https://github.com/appium/appium/blob/master/CONDUCT.md)\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Nightwatch\n\nContributions to Nightwatch are always welcome but please try to follow these guidelines when sending in something as it will help addressing the issue quicker and more smoothly.\n\n__Please do not ask for assistance in the Issues list.__ Join our [Discord server](https://discord.com/invite/SN8Da2X) to ask questions and seek help.\n\nAssistance requests posted in the Issues list are usually closed right away.\n\n## Code of Conduct\n\nContributors are expected to adhere to the [Code of Conduct](CODE_OF_CONDUCT.md).\n\n## Submit an issue\n\nBefore submitting a new issues, try searching for a similar one here: https://github.com/nightwatchjs/nightwatch/search?type=Issues and add your scenario there and anything else which you think will help with fixing it;\n\nIf you are filing a bug report, regression issue or what it appears to be strange behaviour, please follow the steps below:\n\n1. Please write an elaborate title which explains the problem as accurate as possible\n   For instance:\n   - __not helpful__: \"Issue with tags\"\n   - __much better__: \"Tags don't work when combined with --skiptags option\"\n2. Include a sample test which reproduces the problem you're experiencing. The test should be against a __public url__. The test and other info should be posted inline, attachments will be ignored;\n3. Include the verbose output, if possible (run nightwatch with `--verbose` argument);\n4. Include your configuration (try to leave out the irrelevant bits);\n5. Also include: Nightwatch version, Node.js version, OS version and Webdriver/Selenium Server version;\n6. Please try not to report issues you have with individual browser drivers which cannot or should not be solved in Nightwatch.\n\n## Requesting a feature\n\nFeature requests are welcome.\n\n1. Indicate in the issue title that it is a feature/enhancement request;\n2. Explain the use case and include a sample test case and/or usage, if possible;\n3. Try to submit enhancements that you cannot build with custom commands/assertions and something that will benefit the community;\n4. Same as for issues, add your comments/vote to an existing feature request if you'd like to see it implemented.\n\n## Submitting a pull request\n\nThanks in advance for your contribution.\n\n1. Follow the usual git workflow for submitting a pull request:\n   - Fork and clone the project.\n   - Create a new branch from main (e.g. `features/my-new-feature` or `issue/123-my-bugfix`).\n   - Add your changes.\n   - Try to run some Nightwatch example tests locally to test the functionality after making your changes: `node ./bin/nightwatch examples/tests/ecosia.js --env chrome`.\n   - Run Nightwatch unit tests locally: `npm test`;  \n     Or, run individual tests: `npx mocha test/src/api/commands/client/testWaitUntil.js`.\n   - Commit your changes and create a pull request.\n\n   __Note:__ When running Nightwatch example test for the first time, if you encounter _\"Cannot read source\"_ error, go to `nightwatch.conf.js` file and set 'page_objects_path' and 'custom_commands_path' configs to `[]`.\n\n2. If you're fixing a bug, also create an issue if one doesn't exist yet.\n3. If it's a new feature/enhancement, explain why do you think it's necessary.\n4. If your change include drastic or low level changes please discuss them to make sure they will be accepted and what the impact will be.\n5. If your change is based on existing functionality, please consider refactoring first. Pull requests that duplicate code will not make it in very quick, if at all.\n6. Do not include changes that are not related to the issue at hand.\n7. Follow the same coding style with regards to spaces, semicolons, variable naming etc.\n8. Always add tests - after all this _is_ a testing framework.\n"
  },
  {
    "path": "LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014-2021, Pine View Software AS. https://pineview.io                           \nCopyright (c) 2022, BrowserStack Limited. https://www.browserstack.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, 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": "README.md",
    "content": "# Nightwatch.js\n\n[![npm](https://img.shields.io/npm/v/nightwatch.svg)](https://www.npmjs.com/package/nightwatch)\n[![Node.js CI](https://github.com/nightwatchjs/nightwatch/actions/workflows/build-node.yaml/badge.svg?branch=main)](https://github.com/nightwatchjs/nightwatch/actions/workflows/build-node.yaml)\n[![codecov](https://codecov.io/gh/nightwatchjs/nightwatch/branch/main/graph/badge.svg?token=MSObyfECEh)](https://codecov.io/gh/nightwatchjs/nightwatch)\n[![Discord][discord-badge]][discord]\n\n\n\n<p align=\"center\">\n  <img alt=\"Nightwatch.js Logo\" src=\"https://raw.githubusercontent.com/nightwatchjs/nightwatch/main/.github/assets/nightwatch-logo.png\" width=300 />\n</p>\n\n#### [Homepage](https://nightwatchjs.org) &bullet; [Developer Guide](https://nightwatchjs.org/guide) &bullet; [API Reference](https://nightwatchjs.org/api) &bullet; [About](https://nightwatchjs.org/about) &bullet; [Blog](https://nightwatchjs.org/blog)\n\nNightwatch is an integrated testing framework powered by Node.js and using the [W3C Webdriver API](https://www.w3.org/TR/webdriver/). It is a complete testing solution developed at [BrowserStack](https://www.browserstack.com/) and which can be used for: \n\n☑️ end-to-end testing of web applications and websites\n\n☑️ component testing in isolation (React / Vue / Storybook / Angular)\n\n☑️ Node.js unit, visual regression testing, accessibility testing & API testing\n\n☑️ Native mobile app testing on Android & iOS\n\n## 🚀 Nightwatch v3\n[What's New](https://nightwatchjs.org/guide/overview/whats-new-in-v3.html) | [Release Notes](https://github.com/nightwatchjs/nightwatch/releases/tag/v3.0.1) | [Discussions](https://github.com/nightwatchjs/nightwatch/discussions)\n\nNightwatch v3 is an all new generation that has been built around these three pillars:\n\n* **Developer Experience** : The entire experience from getting started, to writing and debugging tests, has been redesigned for speed, stability, and consistent non-flaky results.\n\n* **Mobile first**: Test your web or native, iOS and Android, mobile applications on simulators, real mobile devices or a cloud grid like BrowserStack.\n\n* **One test automation framework**: Run all types of tests from unit, component, and E2E to API, visual, and accessibility with a single framework.\n\nThe [Nightwatch v3](https://github.com/nightwatchjs/nightwatch/releases/tag/v3.0.1) is not just a new version, it’s the result of months of engineering effort to reimagine test automation for the future. Try it out in 60 seconds and see it in action.  \n\n## ⚙️ Get started in 60 seconds\n\n#### 1. Install Nightwatch from NPM\n\nFrom your existing project's root dir:\n\n```sh\nnpm init nightwatch@latest\n```\n\nor, if you want to initialize a new project:\n\n\n```sh\nnpm init nightwatch@latest ./path/to/new/project\n```\n\n\n![nightwatch-cli-gif](https://user-images.githubusercontent.com/39924567/174841680-59664ff6-da2d-44a3-a1df-52d22c69b1e2.gif)\n\n#### 2. Answer a few questions about your preferred setup:\n\n- What is your Language - Test Runner setup? \n- Where do you want to run your e2e tests? \n- Where you'll be testing on? \n- Where do you plan to keep your end-to-end tests? \n- What is the base_url of your project? \n\nNightwatch will do the entire setup for you based on your answers.\n\n#### 3. Run a Demo Test:\n\nNightwatch comes with a few examples, which are automatically copied to your Nightwatch project during the setup and can also be used as boilerplate to write your own tests on top of them.\n\nYou can follow the instructions given at the end of the setup to run your first test with Nightwatch.\n\n<img width=\"413\" alt=\"image\" src=\"https://user-images.githubusercontent.com/39924567/174763723-aff4d501-6320-402c-81cc-de75fbb5e8f0.png\">\n\n---\n\n## Nightwatch mobile app testing\n\nNightwatch enables automation testing of native mobile applications via Appium. It combines the robustness of Appium with the enhanced developer experience provided by Nightwatch. It enables end-to-end functional testing of native mobile apps on Android and iOS devices. Try it now\n\n## Go beyond E2E\n### [Component testing](https://nightwatchjs.org/guide/component-testing/introduction.html)\n\nWith Nightwatch you can test components in isolation by mounting them in the browser. Nightwatch 2 added support for component testing for popular web frameworks such as\n\n1. [React](https://nightwatchjs.org/guide/component-testing/testing-react-components.html)\n2. [VueJS](https://nightwatchjs.org/guide/component-testing/vite-plugin.html)\n3. [Angular](https://nightwatchjs.org/guide/component-testing/angular-component-testing.html)\n4. [Storybook](https://nightwatchjs.org/guide/component-testing/storybook-component-testing.html)\n\n### Nightwatch unit tests\n\nThe tests for Nightwatch are written using Mocha.\n\n1. **Clone the project**\n\n   ```bash\n   git clone https://github.com/nightwatchjs/nightwatch.git\n\n   # change directory\n   cd nightwatch\n\n   # install the dependencies\n   npm install\n   ```\n\n2. **Run tests**\n\n   To run the complete test suite:\n\n   ```bash\n   npm test\n   ```\n\n   To check test coverage, run the command:\n\n   ```bash\n   npm run mocha-coverage\n   ```\n\n   and then open the generated coverage/index.html file in your browser.\n\nSee [Unit testing guide](https://nightwatchjs.org/guide/writing-tests/write-nodejs-unit-integration-tests.html) for more details.\n\n### Other types of testing\n#### [Visual Regression Testing](https://nightwatchjs.org/guide/writing-tests/visual-regression-testing.html)\n\nNightwatch v3 introduces visual regression testing as an in-house plugin. The plugin takes care of\n\n1. Capturing screenshots\n2. Comparison with baseline to highlight visual differences\n3. Report to review the differences\n4. Approve the changes\n\nVRT can be done on real desktop & mobile browsers. Also, VRT can be run on components as part of component testing as well.\n#### [API Testing](https://nightwatchjs.org/guide/writing-tests/api-testing.html)\n\nAPI testing is now available with Nightwatch v3. The following functionality can be achieved with API testing\n\n1. Request assertions\n2. Response assertions\n3. Viewing API tests in the HTML report\n4. Mock server\n\n#### [Accessibility Testing](https://nightwatchjs.org/guide/using-nightwatch/accessibility-testing.html)\nNightwatch v3 packages the aXe-core package developed by Deque Systems as a plugin. It enables 90 different types of accessibility tests for WCAG compliance.\n\n## 🦉 About Nightwatch\nNightwatch was initially built by [@pineviewlabs](https://github.com/pineviewlabs/) - an independent software consultancy based in Oslo, Norway, with help from [contributors](https://github.com/nightwatchjs/nightwatch/graphs/contributors). In mid 2021, Nightwatch has become a part of the [@BrowserStack](https://github.com/browserstack) family and it is being developed further at the BrowserStack Open-source Program Office. Read more on [our blog](https://nightwatchjs.org/blog/nightwatch-has-joined-the-browserstack-family.html).\n\n## Contributing\n\nWe welcome any and all contributions from the community which can help improve Nightwatch. Please check out [CONTRIBUTING.md](CONTRIBUTING.md) for more extensive contributing guidelines.\n\n## Licence\n[MIT](https://github.com/nightwatchjs/nightwatch/blob/main/LICENSE.md)\n\n[discord-badge]: https://img.shields.io/discord/618399631038218240.svg?color=7389D8&labelColor=6A7EC2&logo=discord&logoColor=ffffff&style=flat-square&label=discord\n[discord]: https://discord.gg/SN8Da2X\n"
  },
  {
    "path": "api/README.md",
    "content": "# Nightwatch API Commands\nPublic commands api exported by Nightwatch in order to be extended upon from outside.\n\n**Example:**\n\n```js\nconst {Quit: quit} = require('nightwatch/api');\n\nmodule.exports = CustomQuit extends Quit {\n  async command(cb = function(r) {return r}) {\n    console.log('from custom quit command');\n    \n    await super.command(cb);\n  }\n}\n```\n\n**This is a work in progress.** \n\n## Element commands:\n  - ### Finding elements:\n    - [findElement](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/element-commands/findElement.js)\n    - [findElements](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/element-commands/findElements.js)\n    - [element](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/protocol/element.js)\n    - [elements](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/protocol/elements.js)\n    - [elementIdElement](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/protocol/elementIdElement.js)\n    - [elementIdElements](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/protocol/elementIdElements.js)\n    - [waitForElementPresent](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/element-commands/waitForElementPresent.js)\n    - [waitForElementNotPresent](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/element-commands/waitForElementNotPresent.js)\n    - [waitForElementVisible](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/element-commands/waitForElementVisible.js)\n    - [waitForElementNotVisible](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/element-commands/waitForElementNotVisible.js)\n  - ### Element interaction:\n      - [clearValue](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/element-commands/clearValue.js)\n      - [click](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/element-commands/click.js)\n      - [moveToElement](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/element-commands/moveToElement.js)\n      - [setValue](https://github.com/nightwatchjs/nightwatch/blob/main/lib/api/element-commands/setValue.js)\n  - ### Element state:\n  - ### Element location:\n  - ### Element location:\n\n## Document handling:\n\n## Session related:\n\n## Navigation:\n\n## Window related:\n\n## Frames:\n\n## User actions:\n\n## User prompts:\n\n## Mobile related:\n\n## Utilities & Debugging:\n\n\n\n"
  },
  {
    "path": "api/index.js",
    "content": "const path = require('path');\nconst exportedCommands = [\n  'element-commands/findElement.js',\n  'element-commands/findElements.js',\n  'element-commands/element.js',\n  'element-commands/elements.js',\n  'element-commands/elementIdElement.js',\n  'element-commands/elementIdElements.js',\n  'element-commands/waitForElementPresent.js',\n  'element-commands/waitForElementNotPresent.js',\n  'element-commands/waitForElementVisible.js',\n  'element-commands/waitForElementNotVisible.js',\n  'protocol/quit.js'\n];\n\nconst basePath = '../lib/api';\nconst Commands = {};\nconst props = exportedCommands.reduce((prev, fileName) => {\n  const commandName = fileName.substring(fileName.lastIndexOf('/') + 1).replace('.js', '');\n  prev[commandName] = {\n    configurable: true,\n    get: function() {\n      return require(path.join(basePath, fileName));\n    }\n  };\n\n  return prev;\n}, {});\n\nObject.defineProperties(Commands, props);\n\nmodule.exports = Commands;\n"
  },
  {
    "path": "bin/.gitignore",
    "content": "selenium-server-standalone-*\nchromedriver\nchromedriver-*\nphantomjs\nIEDriverServer_*\n"
  },
  {
    "path": "bin/nightwatch",
    "content": "#!/usr/bin/env node\n\nconst semver = require('semver');\nconst {Logger} = require('../lib/utils');\nconst requiredVersion = require('../package.json').engines.node;\n\nfunction checkNodeVersion (wanted, id) {\n  if (!semver.satisfies(process.version, wanted)) {\n    Logger.error('You are using Node ' + process.version + ', but this version of ' + id +\n      ' requires Node ' + wanted + '.\\nPlease upgrade your Node version.'\n    );\n    process.exit(1);\n  }\n}\n\ncheckNodeVersion(requiredVersion, 'nightwatch');\n\nrequire('./runner.js');\n\n"
  },
  {
    "path": "bin/runner.js",
    "content": "/**\n * Module dependencies\n */\nconst Nightwatch = require('../lib/index.js');\nconst {Logger, shouldReplaceStack, alwaysDisplayError} = require('../lib/utils');\n\ntry {\n  Nightwatch.cli(function (argv) {\n    argv._source = argv['_'].slice(0);\n\n    const runner = Nightwatch.CliRunner(argv);\n\n    return runner\n      .setupAsync()\n      .catch((err) => {\n        if (err.code === 'ERR_REQUIRE_ESM') {\n          err.showTrace = false;\n        }\n\n        throw err;\n      })\n      .then(() => runner.runTests())\n      .catch((err) => {\n        if (!err.displayed || (alwaysDisplayError(err) && !err.displayed)) {\n          Logger.error(err);\n        }\n\n        runner.processListener.setExitCode(10).exit();\n      });\n  });\n} catch (err) {\n  const {message} = err;\n  err.message = 'An error occurred while trying to start the Nightwatch Runner:';\n  err.showTrace = !shouldReplaceStack(err);\n  err.detailedErr = message;\n\n  Logger.error(err);\n\n  process.exit(2);\n}\n"
  },
  {
    "path": "bin/show_survey.js",
    "content": "#!/usr/bin/env node\n\n// eslint-disable-next-line\nconsole.log('\\t  👋 Hey there! Thanks for installing Nightwatch. \\n\\n\\tPlease let us know what features you\\'d like to see \\n\\tin Nightwatch v2.0 by taking this quick survey: \\n\\n\\t\\thttps://forms.gle/zBhbjdsDE77hTHSB7\\n');\n"
  },
  {
    "path": "codecov.yml",
    "content": "codecov:\n  require_ci_to_pass: yes\n\ncoverage:\n  precision: 2\n  round: down\n  range: \"70...100\"\n\nparsers:\n  gcov:\n    branch_detection:\n      conditional: yes\n      loop: yes\n      method: no\n      macro: no\n\ncomment: false"
  },
  {
    "path": "examples/.gitignore",
    "content": "reports\nscreens\n"
  },
  {
    "path": "examples/cucumber-js/README.md",
    "content": "# Using Cucumber.js with Nightwatch 2\n\nNightwatch 2 brings integrated support for using [Cucumber.js](https://cucumber.io/) directly as an alternative test runner. No other plugins are necessary, other than the [Cucumber library](https://www.npmjs.com/package/@cucumber/cucumber) itself (version 7.3 or higher). \n\nSimply run the following in the same project where Nightwatch is also installed:\n\n```sh\n$ npm i @cucumber/cucumber --save-dev\n```\n\n\n## Configuration\n```js\n{\n  test_runner: {\n    // set cucumber as the runner\n    type: 'cucumber',  \n      \n    // define cucumber specific options  \n    options: {\n      //set the feature path\n      feature_path: 'examples/cucumber-js/*/*.feature',\n      \n      // start the webdriver session automatically (enabled by default)\n      auto_start_session: true,\n    \n      // use parallel execution in Cucumber  \n      parallel: 2 // set number of workers to use (can also be defined in the cli as --parallel 2\n    }\n  },\n  \n  src_folders: ['examples/cucumber-js/features/step_definitions']\n}\n```\n\n## CLI Options\n| option             |  description |\n|------------------------|------------------------------|\n| `--dry-run`        | Do all the aggregation work of looking at your feature files, loading your support code etc but without actually executing the tests. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/dry_run.md)\n| `--name`           | Specify a scenario by its name matching a regular expression. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/cli.md#running-specific-features)    \n| `--tags`             | Use tags to run specific scenario or features. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/cli.md#tags)\n| `--require`        | Use `--require <GLOB OR DIR OR FILE>` to explicitly require support files before executing the features. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/cli.md#requiring-support-files)\n| `--format`           | Use `--format <TYPE[:PATH]>` to specify the format of the output. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/cli.md#formats)\n| `--format-options`   | Many formatters, including the built-in ones, support some configurability via options. You can provide this data as a JSON literal via the --format-options CLI option. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/formatters.md#options)         \n| `--fail-fast`        | Abort the run on first failure (default: false). [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/cli.md#--fail-fast)        \n| `--retries`            | Use `--retries <NUMBER-OF-ATTEMPT>` to have Cucumber attempt it multiple times until either it passes or the maximum number of attempts is reached. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/retry.md#retry)       \n| `--retry-tag-filter` |  Use `--retry-tag-filter` to retry failed scenarios based on tags. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/retry.md#targeting-scenarios)\n| `--require-module`   | [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/cli.md#transpilation)\n| `--no-strict`        | By default, cucumber runner works in strict mode, meaning it will fail if there are pending steps.         \n| `--parallel`         | Use `--parallel <NUMBER-OF-WORKER-THREADS>` to run your scenarios in parallel. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/parallel.md#parallel)               \n| `--profile`          | As of now only `cucumber.js` is considered while picking up profiles. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/profiles.md)        \n| `--world-parameters` | Provide this data as a JSON literal via the `--world-parameters`. [read more](https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/world.md#world-parameters)\n\n\n## Running\nCucumber spec files/step definition files can be provided in `src_folders` in Nightwatch config or as a CLI argument.\n\nWith `src_folders` defined:\n\n```sh\n$ npx nightwatch \n```\n\nWithout `src_folders` defined:\n\n```sh\n$ npx nightwatch examples/cucumber-js/features/step_definitions \n```\n\nParallel running using 2 workers:\n\n```sh\n$ nightwatch examples/cucumber-js/features/step_definitions --parallel 2 \n```\n\nUse other [test runner options](https://nightwatchjs.org/guide/running-tests/command-line-options.html) as usual:\n\n```sh\n$ npx nightwatch examples/cucumber-js/features/step_definitions --headless\n```\n\n## Disable the automatic session start\nYou might need sometimes to not start the Webdriver session automatically after Nightwatch is instantiated. For this purpose, Nightwatch provides the instance available as `this.client`, which contains an `launchBrowser()` method.\n\n### Configuration:\n```js\ntest_runner: {\n  type: 'cucumber',\n  options: {\n    feature_path: 'examples/cucumber-js/*/*.feature',\n    auto_start_session: false\n  }\n}\n```\n\nYou can then use an extra setup file that you can pass as an extra `--require` to Nightwatch, which will be forwarded to Cucumber. In the extra setup file, you can add other operations needed to be executed before the session is started.\n\n#### Example _extra_setup.js:\n\nRemember to set the `browser` on `this` so it can be closed automatically by Nightwatch. Otherwise, remember to call `.quit()` in your own Cucumber `After()` hooks. \n\n```js\nconst {Before} = require('@cucumber/cucumber');\n\nBefore(async function(testCase) {\n  if (!this.client) {\n    console.error('Nightwatch instance was not created.');\n\n    return;\n  }\n\n  this.client.updateCapabilities({\n    testCap: 'testing'\n  });\n\n  this.browser = await this.client.launchBrowser();\n});\n```\n\n#### Nightwatch setup file for Cucumber\n\nYou might also want to inspect the built-in setup file that Nightwatch uses for initializing the Cucumber runner. It is available in our project root folder at [/cucumber-js/_setup_cucumber_runner.js](https://github.com/nightwatchjs/nightwatch/blob/v2/cucumber-js/_setup_cucumber_runner.js).\n\n#### Run with extra setup:\n\n```sh\n$ nightwatch examples/cucumber-js/features/step_definitions --require {/full/path/to/_extra_setup.js}\n```\n\n## Reporting\nWhen using the integrated Cucumber test runner, you need to use the Cucumber [formatters](https://github.com/cucumber/cucumber-js/blob/main/docs/formatters.md) for generating output.\n\nNightwatch reporters (like JUnit XML reports or the [global custom reporter](https://nightwatchjs.org/guide/extending-nightwatch/custom-reporter.html)) are not available. The main reason is that reporting is delegated to the Cucumber CLI. You can also [write your own](https://github.com/cucumber/cucumber-js/blob/main/docs/custom_formatters.md) Cucumber formatter.\n\nNightwatch will forward `--format` and `--format-options` CLI arguments, if present, to Cucumber.\n\nBy default, the `progress` formatter is used. Here's how the output looks like when running the example tests in Firefox:\n\n```sh\nℹ Connected to GeckoDriver on port 4444 (1740ms).\nUsing: firefox (92.0.1) on MAC (20.6.0).\n\n..  ✔ Testing if the page title equals 'Rijksmuseum Amsterdam, home of the Dutch masters' (4ms)\n.  ✔ Element <#rijksmuseum-app> was visible after 46 milliseconds.\n.  ✔ Testing if element <.search-results> contains text 'Operation Night Watch' (1994ms)\n...  ✔ Testing if the page title equals 'Rijksmuseum Amsterdam, home of the Dutch masters' (8ms)\n.  ✔ Element <#rijksmuseum-app> was visible after 49 milliseconds.\n.  ✔ Testing if element <.search-results> contains text 'The Night Watch, Rembrandt van Rijn, 1642' (1427ms)\n.\n\n2 scenarios (2 passed)\n10 steps (10 passed)\n0m13.024s (executing steps: 0m12.998s)\n```\n\n\n"
  },
  {
    "path": "examples/cucumber-js/features/nightwatch.feature",
    "content": "Feature: Google Search\nBackground: Background name\n  Given I open the Rijksmuseum page\n  And I dismiss the cookie dialog\n  Then the title is \"Rijksmuseum Amsterdam, home of the Dutch masters\"\n\n@a @b\nScenario: Searching the Rijksmuseum\n  Given I search \"night watch\"\n  Then Body contains \"Operation Night Watch\"\n\n@a @b\nScenario: Searching the Rijksmuseum-1\n  Given I search \"night watch\"\n  Then Body contains \"The Night Watch, Rembrandt van Rijn, 1642\"\n"
  },
  {
    "path": "examples/cucumber-js/features/step_definitions/nightwatch.js",
    "content": "const {Given, Then, When, Before} = require('@cucumber/cucumber');\n\nGiven(/^I open the Rijksmuseum page$/, function() {\n  return browser.navigateTo('https://www.rijksmuseum.nl/en');\n});\n\nGiven(/^I dismiss the cookie dialog$/, async function() {\n  const cookieDialogVisible = await browser.isVisible({\n    selector: '.cookie-consent-bar-wrap',\n    suppressNotFoundErrors: true\n  });\n\n  if (cookieDialogVisible) {\n    return browser.click('.cookie-consent-bar-wrap button.link');\n  }\n});\n\nGiven(/^I search \"([^\"]*)\"$/, async function(searchTerm) {\n  // FIXME: chaining the click command to the rest of the commands causes an uncaughtRejection in case of an element locate error\n  await browser.pause(1000).click('a[aria-label=\"Search\"]');\n\n  return browser.waitForElementVisible('#rijksmuseum-app')\n    .setValue('input.search-bar-input[type=text]', [searchTerm, browser.Keys.ENTER])\n    .pause(1000);\n});\n\nThen(/^the title is \"([^\"]*)\"$/, function(title) {\n  return browser.assert.titleEquals(title);\n});\n\nThen(/^Body contains \"([^\"]*)\"$/, function(contains) {\n  return  browser.assert.textContains('.search-results', contains);\n});\n"
  },
  {
    "path": "examples/custom-assertions/testCustomAssertion.js",
    "content": "const util = require('util');\n\nexports.assertion = function(selector, attribute, expected, msg) {\n  let DEFAULT_MSG = 'Testing if attribute %s of <%s> contains \"%s\".';\n  let MSG_ELEMENT_NOT_FOUND = `${DEFAULT_MSG} Element could not be located.`;\n  let MSG_ATTR_NOT_FOUND = `${DEFAULT_MSG} Element does not have a ${attribute} attribute.`;\n\n  this.message = msg || util.format(DEFAULT_MSG, attribute, selector, expected);\n\n  this.expected = function() {\n    return expected;\n  };\n\n  this.pass = function(value) {\n    return value === expected;\n  };\n\n  this.failure = function(result) {\n    let failed = (result === false) ||\n      // no such element\n      result && (result.status === -1 || result.value === null);\n\n    if (failed) {\n      let defaultMsg = MSG_ELEMENT_NOT_FOUND;\n      if (result && result.value === null) {\n        defaultMsg = MSG_ATTR_NOT_FOUND;\n      }\n      this.message = msg || util.format(defaultMsg, attribute, selector, expected);\n    }\n\n    return failed;\n  };\n\n  this.value = function(result) {\n    return result.value;\n  };\n\n  this.command = function(callback) {\n    return this.api.getAttribute(selector, attribute, callback);\n  };\n\n};\n"
  },
  {
    "path": "examples/custom-commands/angular/getElementsInList.js",
    "content": "module.exports = class AngularCommand {\n  async command(listName, cb = function(r) {return r}) {\n    return this.api.executeScript(function(listName) {\n      // executed in the browser context\n      // eslint-disable-next-line\n      var elements = document.querySelectorAll('*[ng-repeat$=\"'+listName+'\"]');\n      if (elements) {return elements}\n      // eslint-disable-next-line\n      return null;\n    }, [listName], async function(result) {\n      const cbResult = await cb(result);\n\n      if (cbResult.value) {\n        return cbResult.value;\n      }\n\n      return cbResult;\n    });\n  }\n};\n"
  },
  {
    "path": "examples/custom-commands/strictClick.js",
    "content": "module.exports = {\n  command: function(selector){\n    return this.waitForElementVisible(selector)\n      .click(selector);\n  }\n};\n"
  },
  {
    "path": "examples/globals.json",
    "content": "{\n  \"default\" : {\n    \"myGlobal\" : 1\n  },\n  \"test_env\" : {\n    \"myGlobal\" : 2\n  }\n}\n"
  },
  {
    "path": "examples/globalsModule.js",
    "content": "module.exports = {\n  // this controls whether to abort the test execution when an assertion failed and skip the rest\n  // it's being used in waitFor commands and expect assertions\n  abortOnAssertionFailure: true,\n\n  // this will overwrite the default polling interval (currently 500ms) for waitFor commands\n  // and expect assertions that use retry\n  waitForConditionPollInterval: 500,\n\n  // default timeout value in milliseconds for waitFor commands and implicit waitFor value for\n  // expect assertions\n  waitForConditionTimeout: 5000,\n\n  // this will cause waitFor commands on elements to throw an error if multiple\n  // elements are found using the given locate strategy and selector\n  throwOnMultipleElementsReturned: false,\n\n  // controls the timeout value for async hooks. Expects the done() callback to be invoked within this time\n  // or an error is thrown\n  asyncHookTimeout: 10000,\n\n  // controls the timeout value for when running async unit tests. Expects the done() callback to be invoked within this time\n  // or an error is thrown\n  unitTestsTimeout: 2000,\n\n  // controls the timeout value for when executing the global async reporter. Expects the done() callback to be invoked within this time\n  // or an error is thrown\n  customReporterCallbackTimeout: 20000,\n\n  // Automatically retrying failed assertions - You can tell Nightwatch to automatically retry failed assertions until a given timeout is reached, before the test runner gives up and fails the test.\n  retryAssertionTimeout: 1000,\n\n  'default': {\n    myGlobal: function() {\n      return 'I\\'m a method';\n    }\n  },\n\n  'test_env': {\n    myGlobal: 'test_global',\n    beforeEach: function() {\n\n    }\n  },\n\n  before(cb) {\n    //console.log('GLOBAL BEFORE')\n    cb();\n  },\n\n  beforeEach(browser, cb) {\n    //console.log('GLOBAL beforeEach')\n    cb();\n  },\n\n  after(cb) {\n    //console.log('GLOBAL AFTER')\n    cb();\n  },\n\n  afterEach(browser, cb) {\n    browser.perform(function() {\n      //console.log('GLOBAL afterEach')\n      cb();\n    });\n  },\n\n  reporter(results, cb) {\n    cb();\n  }\n};\n"
  },
  {
    "path": "examples/pages/google/consent.js",
    "content": "class ConsentCommand {\n  turnOffSearchCustomization() {\n    this.page.section.customizeSearch.click('@turnOffButton');\n\n    return this;\n  }\n\n  turnOffYoutubeHistory() {\n    this.page.section.youtubeHistory.click('@turnOffButton');\n\n    return this;\n  }\n\n  turnOffAdPersonalization() {\n    this.page.section.adPersonalization.click('@turnOffButton');\n\n    return this;\n  }\n\n  confirm() {\n    this.page.section.consentForm.click('@submitButton');\n\n    return this;\n  }\n\n  turnOffEverything() {\n    return this.turnOffSearchCustomization()\n      .turnOffYoutubeHistory()\n      .turnOffAdPersonalization()\n      .confirm();\n  }\n}\n\nconst createSectionFor = (text) => {\n  return Object.assign({\n    selector: `//div[contains(.,\"${text}\")]`,\n    locateStrategy: 'xpath'\n  }, {\n    elements: {\n      turnOffButton: 'button[aria-label^=\"Turn off\"]'\n    }\n  });\n};\n\nmodule.exports = {\n  url: 'http://google.com',\n  commands: ConsentCommand,\n\n  elements: {\n    consentModal: 'form[action^=\"https://consent.google\"]'\n  },\n\n  sections: {\n    customizeSearch: createSectionFor('Search customization'),\n    youtubeHistory: createSectionFor('YouTube History'),\n    adPersonalization: createSectionFor('Ad personalization'),\n\n    consentForm: {\n      selector: 'form[action^=\"https://consent.google\"]',\n      elements: {\n        submitButton: 'button'\n      }\n    }\n  }\n};\n"
  },
  {
    "path": "examples/pages/google/search.js",
    "content": "const searchCommands = {\n  submit() {\n    this.waitForElementVisible('@submitButton', 1000)\n      .click('@submitButton');\n\n    this.pause(1000);\n\n    return this; // Return page object for chaining\n  }\n};\n\nconst consentModal = '[aria-modal=\"true\"]';\n\nmodule.exports = {\n  url: 'https://google.no',\n  commands: [\n    searchCommands\n  ],\n\n  sections: {\n    consentModal: {\n      selector: consentModal,\n      elements: {\n        rejectAllButton: '.GzLjMd button:nth-child(1)'\n      }\n    }\n  },\n\n  elements: {\n    consentModal,\n\n    searchBar: {\n      selector: 'textarea[name=q]'\n    },\n\n    submitButton: {\n      selector: 'input[value=\"Google Search\"]'\n    }\n  }\n};\n"
  },
  {
    "path": "examples/pages/google/searchResults.js",
    "content": "const util = require('util');\n\n// starting xpath with './/' tells browser to begin search from the current element,\n// while starting with '//' tells browser to begin search from the start of html document.\nconst menuXpath = './/span[contains(text(), \"%s\")]';\n\nconst menuCommands = {\n  productIsSelected: function (product, callback) {\n    var self = this;\n\n    return this.getAttribute(product, 'class', function (result) {\n      const isSelected = result.value.indexOf('hdtb-msel') > -1;\n      callback.call(self, isSelected);\n    });\n  }\n};\n\nmodule.exports = {\n  elements: {\n    results: {selector: '#rso'}\n  },\n  sections: {\n    menu: {\n      selector: 'div[role=\"navigation\"] div[data-st-cnt=\"mode\"]',\n      commands: [menuCommands],\n      elements: {\n        maps: {\n          selector: util.format(menuXpath, 'Maps'),\n          locateStrategy: 'xpath',\n          index: 0\n        },\n        videos: {\n          selector: util.format(menuXpath, 'Videos'),\n          locateStrategy: 'xpath',\n          index: 0\n        },\n        images: {\n          selector: util.format(menuXpath, 'Images'),\n          locateStrategy: 'xpath',\n          index: 0\n        },\n        news: {\n          selector: util.format(menuXpath, 'News'),\n          locateStrategy: 'xpath',\n          index: 0\n        }\n      }\n    }\n  }\n};\n"
  },
  {
    "path": "examples/pages/nightwatchFeatures.js",
    "content": "const featuresCommands = {\n  getFeatureCount: function(callback) {\n    this.api.elements(null, this.elements.features, function (result) {\n      if (result.status === 0) {\n        var countResult = {\n          status: 0,\n          value: result.value.length\n        };\n        callback.call(this, countResult);\n      } else {\n        callback.call(this, result);\n      }\n    }.bind(this));\n\n    return this;\n  }\n};\n\nmodule.exports = {\n  commands: [featuresCommands],\n  elements: {\n    featuresHeading: {\n      selector: '#index-container h2',\n      index: 1\n    },\n    features: '#index-container .features h3'\n  }\n};\n"
  },
  {
    "path": "examples/test-app/globals.js",
    "content": "const waitOn = require('wait-on');\nconst {spawn} = require('child_process');\nconst path = require('path');\n\nlet serverPid = null;\nconst serverPort = '13370';\n\nmodule.exports = {\n  before(done) {\n    // serve --listen 13370 ./test-app\n    serverPid = spawn(path.resolve('node_modules/.bin/serve'), ['--listen', serverPort, '--no-request-logging', __dirname], {\n      cwd: process.cwd(),\n      stdio: 'inherit'\n    }).pid;\n\n    waitOn({\n      resources: [`http://localhost:${serverPort}`]\n    }).then(() => {\n      setTimeout(done, 500);\n    });\n\n  },\n\n  after() {\n    if (serverPid) {\n      process.kill(serverPid);\n    }\n  }\n};\n"
  },
  {
    "path": "examples/test-app/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\" />\n  <title>nightwatch-testing-library</title>\n  <style>\n    blockquote {\n      margin: 0;\n      border-left: 4px solid grey;\n      padding-left: 10px;\n      color: grey;\n    }\n\n    section {\n      padding: 10px;\n    }\n  </style>\n\n</head>\n\n<body>\n  <section>\n    <h2>getByPlaceholderText</h2>\n    <input type=\"text\" placeholder=\"Placeholder Text\" />\n  </section>\n  <section>\n    <h2>getByText</h2>\n    <button role=\"button\" onclick=\"this.innerText = 'Button Clicked'\">Unique Button Text</button>\n    <div id=\"nested\">\n      <h3>getByText within</h3>\n      <button onclick=\"this.innerText = 'Button Clicked'\">Button Text</button>\n    </div>\n    <div id=\"nested2\" data-testid=\"nested2\">\n      <h3>getByText within</h3>\n      <button onclick=\"this.innerText = 'Button Clicked'\">Button Text</button>\n      <span>text only in 2nd nested</span>\n      <span>another thing only in 2nd nested</span>\n    </div>\n  </section>\n  <section>\n    <h2>getByLabelText</h2>\n    <label for=\"input-labelled-by-id\">Label For Input Labelled By Id</label>\n    <input type=\"text\" placeholder=\"Input Labelled By Id\" id=\"input-labelled-by-id\" />\n  </section>\n  <section>\n    <h2>getByAltText</h2>\n    <img src=\"data:image/png;base64,\" alt=\"Image Alt Text\" onclick=\"this.style.border = '5px solid red'\" />\n  </section>\n  <section>\n    <h2>getByTestId</h2>\n    <img data-testid=\"image-with-random-alt-tag\" src=\"data:image/png;base64,\"\n      onclick=\"this.style.border = '5px solid red'\" />\n  </section>\n  <section>\n    <h2>configure</h2>\n    <img data-automation-id=\"image-with-random-alt-tag\" src=\"data:image/png;base64,\"\n      onclick=\"this.style.border = '5px solid red'\" />\n  </section>\n  <section>\n    <h2>configure standalone</h2>\n\n    <img data-other-test-id=\"other-id\" src=\"data:image/png;base64,\" onclick=\"this.style.border = '5px solid red'\" />\n  </section>\n  <section>\n    <h2>getAllByText</h2>\n    <button onclick=\"this.innerText = ''\">Thales of Miletus</button>\n    <button onclick=\"this.innerText = ''\">Anaximander of Miletus</button>\n  </section>\n  <section>\n    <h2>navigate</h2>\n    <a href=\"page2.html\">Go to Page 2</a>\n  </section>\n\n  <script>\n    document\n      .querySelector('[data-testid=\"image-with-random-alt-tag\"]')\n      .setAttribute(\"alt\", \"Image Random Alt Text \" + Math.random());\n  </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/test-app/page2.html",
    "content": "<div>\n    <h2>second page</h2>\n</div>\n<section>\n    <section>\n        <h2>configure</h2>\n        <img data-automation-id=\"page2-thing\" src=\"data:image/png;base64,\"\n            onclick=\"this.style.border = '5px solid red'\" />\n    </section>\n</section>"
  },
  {
    "path": "examples/tests/README.md",
    "content": "# Using Mocha as a test runner in Nightwatch 2\n\nNightwatch 2 brings support for Mocha v9 as an alternative test runner which contains most of the existing functionality from the Nightwatch default runner.\n\nWe are still in the process of updating the examples. Please check back here soon."
  },
  {
    "path": "examples/tests/angularTodoTest.js",
    "content": "describe('angularjs homepage todo list', function() {\n\n  it('should add a todo using custom commands', async function(browser) {\n    // adding a new task to the list\n    const elements = await browser\n      .navigateTo('https://angularjs.org')\n      .sendKeys('[ng-model=\"todoList.todoText\"]', 'what is nightwatch?')\n      .click('[value=\"add\"]')\n      .angular.getElementsInList('todoList.todos');\n\n    const taskEl = element(elements[2]);\n\n    // verifying if the third task is the one we have just added\n    // browser.assert.textEquals(taskEl, 'what is nightwatch?');\n\n    await expect(taskEl).text.toEqual('what is nightwatch?');\n\n    // find our task in the list and mark it as done\n    const inputElement = await element(elements[2]).findElement('input');\n    await browser.click(inputElement);\n\n    // verify if there are 2 tasks which are marked as done in the list\n    await expect.elements('*[module=todoApp] li .done-true').count.to.equal(2);\n  });\n\n});\n"
  },
  {
    "path": "examples/tests/bstackdemo/auth.js",
    "content": "describe('Authentication Tests', function () {\n  beforeEach((browser) => browser.navigateTo('https://www.bstackdemo.com'));\n\n  it('Login test', function () {\n    browser\n      .click('#signin')\n      .setValue('#username input', ['demouser', browser.Keys.ENTER])\n      .setValue('#password input', ['testingisfun99', browser.Keys.ENTER])\n      .click('#login-btn')\n      .assert.textEquals('.username', 'demouser', 'demouser had logged in successfuly.');\n  });\n\n  it('Locked account test', function () {\n    browser\n      .click('#signin')\n      .setValue('#username input', ['locked_user', browser.Keys.ENTER])\n      .setValue('#password input', ['testingisfun99', browser.Keys.ENTER])\n      .click('#login-btn')\n      .assert.textContains('.api-error', 'Your account has been locked.');\n  });\n\n  afterEach((browser) => browser.end());\n});\n"
  },
  {
    "path": "examples/tests/bstackdemo/checkout.js",
    "content": "describe('Checkout Test', function () {\n  before((browser) => browser.navigateTo('https://www.bstackdemo.com/'));\n\n  it('checkout products on bstackdemo.com', function (browser) {\n    browser\n      .waitForElementVisible('body')\n      .assert.titleContains('StackDemo')\n      // Filter Google from the avaialble filters\n      .click('input[value=\\'Google\\'] + span')\n      .assert.selected('input[value=\\'Google\\']')\n      // Add different phones to cart\n      .click('[id=\"17\"] .shelf-item__buy-btn')\n      .click('[id=\"18\"] .shelf-item__buy-btn')\n      .assert.elementsCount('.float-cart__shelf-container .shelf-item', 2)\n      // Click checkout\n      .click('.buy-btn')\n      // Loging with given credentials\n      .setValue('#username input', ['demouser', browser.Keys.ENTER])\n      .setValue('#password input', ['testingisfun99', browser.Keys.ENTER])\n      .click('#login-btn')\n      // Fill shipping details\n      .setValue('#firstNameInput', 'John')\n      .setValue('#lastNameInput', 'Doe')\n      .setValue('#addressLine1Input', 'localhost')\n      .setValue('#provinceInput', 'local')\n      .setValue('#postCodeInput', '127001')\n      .click('#checkout-shipping-continue')\n      // Check order successfully placed\n      .assert.textEquals('#confirmation-message', 'Your Order has been successfully placed.');\n  });\n\n  after((browser) => browser.end());\n});\n"
  },
  {
    "path": "examples/tests/chromeCDP_example.js",
    "content": "describe('Chrome DevTools Example', function() {\n\n  this.disabled = this.argv.env !== 'chrome';\n\n  it ('using CDP DOM Snapshot', async function(browser) {\n    await browser.navigateTo('https://nightwatchjs.org');\n\n    const dom = await browser.chrome.sendAndGetDevToolsCommand('DOMSnapshot.captureSnapshot', {\n      computedStyles: []\n    });\n\n    browser.assert.deepStrictEqual(Object.keys(dom), ['documents', 'strings']);\n  });\n});\n"
  },
  {
    "path": "examples/tests/duckDuckGo.js",
    "content": "describe('duckduckgo example', function() {\n\n  this.tags = ['end-to-end'];\n\n  it('Search Nightwatch.js and check results', function(browser) {\n    browser\n      .navigateTo('https://duckduckgo.com')\n      .waitForElementVisible('body')\n      .assert.visible('input[name=\"q\"]')\n      .sendKeys('input[name=\"q\"]', ['Nightwatch.js'])\n      .assert.visible('button[type=submit]')\n      .click('button[type=submit]')\n      .assert.textContains('.react-results--main', 'Nightwatch.js');\n  });\n});\n"
  },
  {
    "path": "examples/tests/ecosia.js",
    "content": "describe('Ecosia.org Demo', function() {\n\n  before(browser => {\n    browser\n      .navigateTo('https://www.ecosia.org/');\n  });\n\n  it('Demo test ecosia.org', function(browser) {\n    browser\n      .waitForElementVisible('body')\n      .assert.titleContains('Ecosia')\n      .assert.visible('input[type=search]')\n      .setValue('input[type=search]', 'nightwatch')\n      .assert.visible('button[type=submit]')\n      .click('button[type=submit]')\n      .assert.textContains('.layout__content', 'Nightwatch.js');\n  });\n\n  after(browser => browser.end());\n});\n"
  },
  {
    "path": "examples/tests/element/dragAndDrop.js",
    "content": "describe('Element Drag & Drop Demo', function () {\n  before(browser => {\n    browser.navigateTo(\n      'https://mdn.github.io/dom-examples/drag-and-drop/copy-move-DataTransfer.html'\n    );\n  });\n\n  it('move element demo', async function (browser) {\n    const srcMoveElem = browser.element('#src_move'); // returns a Nightwatch Element Wrapper with loads of element commands.\n\n    // pause to see the initial state\n    browser.pause(1000);\n\n    // drag src element 80 pixels below.\n    srcMoveElem.dragAndDrop({x: 0, y: 80});\n  });\n\n  it('copy element demo', async function (browser) {\n    const srcCopyElem = browser.element('#src_copy'); // returns a Nightwatch Element Wrapper with loads of element commands.\n    const destCopyWebElem = await browser.element('#dest_copy'); // awaiting the browser.element command returns a WebElement object (actual result).\n\n    // pause to see the initial state\n    browser.pause(1000);\n\n    // drag src element to dest element.\n    srcCopyElem.dragAndDrop(destCopyWebElem);\n  });\n\n  after((browser) => {\n    // pause to see the final state\n    browser.pause(2000);\n\n    browser.end();\n  });\n});\n"
  },
  {
    "path": "examples/tests/element/elementScreenshot.js",
    "content": "describe('Take Screenshot Demo', function () {\n  before((browser) => {\n    browser.navigateTo('https://nightwatchjs.org/');\n  });\n\n  it('takes screenshot without async-await', function (browser) {\n    browser.waitForElementVisible('body');\n\n    const heading = browser.element('.hero__heading');\n    const screenshot = heading.takeScreenshot();\n    screenshot.then((screenshotData) => {\n      require('fs').writeFile('heading.png', screenshotData, 'base64', (err) => {\n        browser.assert.strictEqual(err, null);\n      });\n    });\n  });\n\n  it('takes screenshot with async-await', async function (browser) {\n    browser.waitForElementVisible('body');\n\n    const heading = browser.element('.hero__heading');\n    const screenshotData = await heading.takeScreenshot();\n\n    require('fs').writeFile('heading1.png', screenshotData, 'base64', (err) => {\n      browser.assert.strictEqual(err, null);\n    });\n  });\n\n  after((browser) => browser.end());\n});\n"
  },
  {
    "path": "examples/tests/element/elementapi-tests.js",
    "content": "describe('queries tests', function() {\n\n  beforeEach(function(browser) {\n    browser.navigateTo('http://localhost:13370');\n  });\n\n  it('getFirstElementChild', async function({element}) {\n    const firstChild = await element.find('#nested').getFirstElementChild().inspectInDevTools('firstChild');\n    await expect(firstChild).to.be.an('h3');\n\n    const lastChild = await element('#nested').getLastElementChild().inspectInDevTools('lastChild');\n    const nextElementSibling = await element('#nested').getNextElementSibling().inspectInDevTools('nextElementSibling');\n    const previousElementSibling = await element('#nested').inspectInDevTools('previousElementSibling');\n  });\n\n  it('assert.present', async function({element}) {\n    await element.findAll('section').nth(1).assert.present();\n  });\n\n  it('assert.hasAttribute', async function({element}) {\n    await element.findAll('section').nth(1).find('button').assert.hasAttribute('role');\n  });\n\n  it('custom element assertion', async function({element}) {\n    await element.findAll('section').nth(1).find('button').assert.customScript(function(element, content) {\n      return element.innerHTML === content;\n    }, ['Unique Button Text'], 'Custom assertion message: button has correct text');\n  });\n\n  it('findByRole', async function({element}) {\n    const button = await element.findAll('section').nth(1).findByRole('button');\n    await expect(button).to.be.an('button');\n\n    await browser.click(button);\n    await expect(button).text.to.equal('Button Clicked');\n  });\n\n  it('findAll', async function({element}) {\n    await element.findAll('section').count().assert.equals(9);\n  });\n\n  it('Button click works', async function(browser) {\n    const button = await browser.element.findByText('Unique Button Text');\n\n    await expect(button).text.not.to.equal('Button Clicked');\n\n    await browser.click(button);\n\n    await expect(button).text.to.equal('Button Clicked');\n  });\n\n  it('findByPlaceholderText', async function ({element, actions}) {\n    const input = await element.findByPlaceholderText('Placeholder Text').assert.visible('Input is visible');\n\n    await expect(input).property('value').not.to.equal('Hello Placeholder');\n\n    // // Uses the User Actions API to type into the input\n    await actions().sendKeys(input, 'Hello Placeholder').perform();\n\n    await expect(input).property('value').to.equal('Hello Placeholder');\n  });\n\n\n  it('findByLabelText', async function ({element}) {\n    const input = await element.findByLabelText('Label For Input Labelled By Id').sendKeys('Hello Input Labelled by Id');\n\n    expect(input).value.toEqual('Hello Input Labelled by Id');\n  });\n\n  it('findByAltText', async function ({element}) {\n    const image = await element.findByAltText('Image Alt Text').click();\n\n    expect(image).css('border').toEqual('5px solid rgb(255, 0, 0)');\n  });\n\n  it('findAllByText', async function ({element}) {\n    const philosophers = await element.findAllByText('of Miletus', {exact: false});\n    expect(philosophers).to.have.length(2);\n  });\n\n\n});\n"
  },
  {
    "path": "examples/tests/element/isCommands.js",
    "content": "describe('Element \"is\" commands Demo', function () {\n  before((browser) => {\n    browser.navigateTo('https://www.ecosia.org/settings');\n  });\n\n  it('Demo', async function (browser) {\n    // accepting cookies to remove modal\n    browser.element('.cookie-consent__actions').getLastElementChild().click();\n\n    const saveButton = browser.element('.settings-form__buttons > .base-button--variant-solid-green');\n    const cancelButton = browser.element('.settings-form__buttons > .base-button--variant-outline');\n\n    saveButton.isVisible().assert.equals(true);\n    cancelButton.isVisible().assert.equals(true);\n\n    saveButton.isEnabled().assert.equals(false);\n    cancelButton.isEnabled().assert.equals(true);\n\n    const newTabCheckbox = browser.element('#e-field-newTab');\n\n    newTabCheckbox.isSelected().assert.equals(false);\n\n    // Clicking the checkbox selects it.\n    // Also our save button becomes enabled.\n    newTabCheckbox.click();\n\n    newTabCheckbox.isSelected().assert.equals(true);\n    saveButton.isEnabled().assert.equals(true);\n\n    // click the cancel button\n    cancelButton.click();\n  });\n\n  after((browser) => browser.end());\n});\n"
  },
  {
    "path": "examples/tests/google.js",
    "content": "describe('sample google search', function() {\n  this.tags = ['google'];\n\n  it('demo test using expect apis', async function(browser) {\n    await browser.navigateTo('http://google.no');\n\n    const consentPresent = await browser.isPresent('[aria-modal=\"true\"][title=\"Before you continue to Google Search\"]');\n\n    // Wait until we are on consent page\n    if (consentPresent === true) {\n      browser\n        .waitForElementVisible('[aria-modal=\"true\"][title=\"Before you continue to Google Search\"]')\n        .click('[aria-modal=\"true\"] div.VDity button:nth-child(1)')\n\n        // Wait until we are on consent page\n        .expect.url().toContain('https://consent.google.no')\n\n        // Turn everything off\n        .click('button[aria-label=\"Turn off Search customization\"]')\n        .click('button[aria-label=\"Turn off YouTube History\"]')\n        .click('button[aria-label=\"Turn off Ad personalization\"]')\n\n        // click on confirm button\n        .click('form[action^=\"https://consent.google.no\"] button')\n\n        // saving the consent form takes some time, no need to check for anything else\n        .pause(1000);\n    }\n\n    let locator;\n    if (browser.isMobile()) {\n      locator = 'form[action=\"/search\"] input[type=search]';\n    } else {\n      locator = 'form[action=\"/search\"] input[type=text]';\n    }\n\n    await browser\n      .waitForElementVisible(locator)\n      .sendKeys(locator, ['Nightwatch.js', browser.Keys.ENTER])\n      .assert.textContains('#rso>:first-child', 'Nightwatch.js')\n      .end();\n  });\n});\n"
  },
  {
    "path": "examples/tests/googlePageObject.js",
    "content": "describe('google search with consent form - page objects', function() {\n  const homePage = browser.page.google.search();\n\n  before(async () => homePage.navigate());\n\n  after(async (browser) => browser.quit());\n\n  it('should find nightwatch.js in results', function (browser) {\n    homePage.setValue('@searchBar', 'Nightwatch.js');\n    homePage.submit();\n\n    const resultsPage = browser.page.google.searchResults();\n    resultsPage.expect.element('@results').to.be.present;\n\n    resultsPage.expect.element('@results').text.to.contain('Nightwatch.js');\n\n    resultsPage.expect.section('@menu').to.be.visible;\n\n    const menuSection = resultsPage.section.menu;\n    menuSection.expect.element('@videos').to.be.visible;\n  });\n});\n"
  },
  {
    "path": "examples/tests/sample-with-relative-locators.js",
    "content": "/* eslint-disable no-undef */\ndescribe('sample with relative locators', function () {\n  before(browser => browser.navigateTo('https://archive.org/account/login'));\n\n  it('locate password input', function (browser) {\n    const passwordElement = locateWith(By.tagName('input')).below(By.css('input[type=email]'));\n\n    browser\n      .waitForElementVisible(passwordElement)\n      .expect.element(passwordElement).to.be.an('input');\n\n    browser.expect.element(passwordElement).attribute('type').equal('password');\n  });\n\n  it('fill in password input', function (browser) {\n    const passwordElement = locateWith(By.tagName('input')).below(By.css('input[type=email]'));\n\n    browser\n      .waitForElementVisible('form.login-form')\n      .setValue(passwordElement, 'password')\n      .assert.valueEquals('input[type=password]', 'password');\n  });\n\n  after(browser => browser.end());\n});\n"
  },
  {
    "path": "examples/tests/selectElement.js",
    "content": "const {Select} = require('selenium-webdriver');\n\nmodule.exports = {\n  before(browser) {\n    browser.url('https://www.selenium.dev/selenium/web/formPage.html');\n  },\n\n  async demoTest(browser) {\n    const selectElement = browser.element('select[name=selectomatic]');\n\n    await browser\n      .perform(async function() {\n        const selectWebElement = await selectElement; // `Select` class expects a WebElement\n\n        const select = new Select(selectWebElement);\n\n        await select.selectByVisibleText('Four');\n      })\n      .assert.selected(await selectElement.findElement('option[value=four]'), 'Forth option is selected');\n  }\n};\n"
  },
  {
    "path": "examples/tests/shadowRootExample.js",
    "content": "describe('Shadow Root example test', function() {\n  it('retrieve the shadowRoot', async function(browser) {\n    browser\n      .navigateTo('https://mdn.github.io/web-components-examples/popup-info-box-web-component/')\n      .waitForElementVisible('form');\n\n    // const shadowId = browser.element('popup-info').getId().map(val => {\n    //   return val + 'shadow';\n    // }).assert.contains('shadow');\n    // console.log('!!! shadowId', shadowId)\n\n    // const elForm = await browser.element.findAllByText('Pop-up info widget', {exact: false}).nth(0);\n    // expect(elForm).to.be.a('h1');\n\n    // const elForm = await browser.element.findAll('form').nth(0);\n    // expect(elForm).to.be.a('form');\n\n    // const formCount = await browser.element.findAll('form').count();\n    // expect(formCount).to.equal(1);\n    //\n    // const elInput = await browser.element.find('form').find('input');\n    // console.log('!!! elInput', elInput);\n    //expect(elInput).to.be.an('input');\n\n\n\n    // const els = await browser.element.findAll('form').count();\n    // console.log('!!! els', els);\n    //\n    // //await expect(shadowId).to.be.a('string').and.to.include('shadow')\n    //\n\n    // no `await` used since `shadowRootEl` is going to be chained further\n    const shadowRootEl = browser.element('popup-info').getShadowRoot();\n    const infoElement = shadowRootEl.find('.info').property('innerHTML');\n    //\n    // //console.log('!!! infoElement', infoElement.assert)\n    //\n    // expect(infoElement)\n    //   .to.be.a('string')\n    //   .and.to.include('card validation code');\n    //\n    // const iconElement = await shadowRootEl.find('.icon');\n    // console.log('!!! iconElement', iconElement)\n    //\n    // const firstElement = await browser.getFirstElementChild(iconElement);\n    //\n    // await expect.element(firstElement).to.be.an('img');\n\n  });\n});\n"
  },
  {
    "path": "examples/tests/vueTodoList.js",
    "content": "/**\n * End-to-end test for the sample Vue3+Vite todo app located at\n * https://github.com/nightwatchjs-community/todo-vue\n */\ndescribe('To-Do List End-to-End Test', function() {\n\n  // using the new element() global utility in Nightwatch 2 to init elements\n  // before tests and use them later\n  const todoElement = element('#new-todo-input');\n  const addButtonEl = element('form button[type=\"submit\"]');\n\n  it('should add a todo using global element()', async function() {\n    ///////////////////////////////////////////////////\n    // browser can now also be accessed as a global   |\n    ///////////////////////////////////////////////////\n\n    // adding a new task to the list\n    await browser\n      .navigateTo('https://todo-vue3-vite.netlify.app/')\n      .sendKeys(todoElement, 'what is nightwatch?')\n      .click(addButtonEl);\n\n    ///////////////////////////////////////////////////\n    // global expect is equivalent to browser.expect  |\n    ///////////////////////////////////////////////////\n\n    // verifying if there are 5 tasks in the list\n    await expect.elements('#todo-list ul li').count.toEqual(5);\n\n    // verifying if the 4th task if the one we have just added\n    const lastElementTask = element({\n      selector: '#todo-list ul li',\n      index: 4\n    });\n\n    await expect(lastElementTask).text.toContain('what is nightwatch?');\n\n    // find our task in the list and mark it as done\n    const inputElement = await lastElementTask.findElement('input[type=\"checkbox\"]');\n    await browser.click(inputElement);\n\n    // verify if there are 3 tasks which are marked as done in the list\n    await expect.elements('#todo-list ul li input:checked').count.toEqual(3);\n  });\n\n});\n"
  },
  {
    "path": "examples/tsconfig.json",
    "content": "{\n    \"extends\": \"../tsconfig\",\n    \"include\": [\".\"]\n}\n"
  },
  {
    "path": "examples/unittests/demoTestAsync.js",
    "content": "const assert = require('assert');\n\nmodule.exports = {\n  '@unitTest': true,\n\n  'demo UnitTest': function (done) {\n    assert.strictEqual('TEST', 'TEST');\n    setTimeout(function() {\n      done();\n    }, 10);\n  }\n};\n"
  },
  {
    "path": "examples/unittests/testUtils.js",
    "content": "const assert = require('assert');\nconst Utils = require('../../dist/utils/');\n\nmodule.exports = {\n  testFormatElapsedTime: function() {\n    var resultMs = Utils.formatElapsedTime(999);\n    assert.strictEqual(resultMs, '999ms');\n\n    var resultSec = Utils.formatElapsedTime(1999);\n    assert.strictEqual(resultSec, '1.999s');\n\n    var resultMin = Utils.formatElapsedTime(122299, true);\n    assert.strictEqual(resultMin, '2m 2s / 122299ms');\n  },\n\n  testGetTestSuiteName: function() {\n    assert.strictEqual(Utils.getTestSuiteName('test-case-one'), 'Test Case One');\n    assert.strictEqual(Utils.getTestSuiteName('test_case_two'), 'Test Case Two');\n    assert.strictEqual(Utils.getTestSuiteName('test.case.one'), 'Test Case One');\n    assert.strictEqual(Utils.getTestSuiteName('testCaseOne'), 'Test Case One');\n  }\n};\n"
  },
  {
    "path": "examples/unittests/testUtilsWithChai.js",
    "content": "const Utils = require('../../dist/utils/');\nconst expect = require('chai').expect;\n\nmodule.exports = {\n  testFormatElapsedTime: function() {\n    var resultMs = Utils.formatElapsedTime(999);\n    var resultSec = Utils.formatElapsedTime(1999);\n    var resultMin = Utils.formatElapsedTime(122299, true);\n\n    expect(resultMs).to.equal('999ms');\n    expect(resultSec).to.equal('1.999s');\n    expect(resultMin).to.equal('2m 2s / 122299ms');\n  },\n\n  testFormatElapsedTimeMore: function() {\n    var resultMs = Utils.formatElapsedTime(999);\n    expect(resultMs).to.equal('999ms');\n  }\n};\n"
  },
  {
    "path": "index.js",
    "content": "module.exports = process.env.NIGHTWATCH_COV ?\n  require('./lib-cov/index') :\n  require('./lib/index');\n"
  },
  {
    "path": "lib/api/_loaders/_base-loader.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst EventEmitter = require('events');\nconst Utils = require('../../utils');\nconst namespacedApi = require('../../core/namespaced-api.js');\nconst ScopedElementAPILoader = require('./element-api.js');\n\nlet __last_deferred__ = null;\nclass BaseLoader extends EventEmitter {\n  static get commandOverrides () {\n    return {\n      element(nightwatchInstance, ...args) {\n        if (nightwatchInstance.settings.backwards_compatibility_mode) {\n          return args[0];\n        }\n\n        return new ScopedElementAPILoader(nightwatchInstance).createElementMethod();\n      }\n    };\n  }\n\n  static handleModuleError(err, fullPath) {\n    const {message} = err;\n\n    const showStackTrace = ['SyntaxError', 'TypeError'].includes(err.name);\n    const error = new Error(`There was an error while trying to load the file ${fullPath}:`);\n    error.detailedErr = `[${err.code || err.name}] ${message};`;\n    error.extraDetail = `\\n Current working directory is: ${process.cwd()}`;\n    error.showTrace = showStackTrace;\n    error.displayed = false;\n    if (showStackTrace) {\n      error.stack = err.stack;\n    }\n\n    throw error;\n  }\n\n  static unflattenNamespace(target, namespace, value) {\n    const key = namespace.shift();\n    if (key) {\n      target[key] = target[key] || {};\n      value = target[key];\n\n      return BaseLoader.unflattenNamespace(target[key], namespace, value);\n    }\n\n    return value;\n  }\n\n  static createDriverCommand(nightwatchInstance, commandName) {\n    return function commandFn({args}) {\n      return nightwatchInstance.transport.driver[commandName](...args).catch((error) => {\n        if (error.remoteStacktrace) {\n          delete error.remoteStacktrace;\n        }\n\n        return {\n          value: null,\n          error\n        };\n      });\n    };\n  }\n\n  static get lastDeferred() {\n    return __last_deferred__;\n  }\n\n  static set lastDeferred(value) {\n    __last_deferred__ = value;\n  }\n\n  get commandQueue() {\n    return this.nightwatchInstance.queue;\n  }\n\n  get loadSubDirectories() {\n    return false;\n  }\n\n  get reporter() {\n    return this.nightwatchInstance.reporter;\n  }\n\n  get api() {\n    return this.nightwatchInstance.api;\n  }\n\n  get elementLocator() {\n    return this.nightwatchInstance.elementLocator;\n  }\n\n  get transport() {\n    return this.nightwatchInstance.transport;\n  }\n\n  get namespace() {\n    return this.__namespace;\n  }\n\n  get module() {\n    return this.__module;\n  }\n\n  set module(val) {\n    this.__module = val;\n  }\n\n  get commandName() {\n    return this.__commandName;\n  }\n\n  get commandFn() {\n    return this.__commandFn;\n  }\n\n  set commandFn(val) {\n    this.__commandFn = val;\n  }\n\n  set commandName(val) {\n    this.__commandName = val;\n  }\n\n  set stackTrace(val) {\n    this.__stackTrace = val;\n  }\n\n  get stackTrace() {\n    return this.__stackTrace;\n  }\n\n  get instance() {\n    return this.__instance;\n  }\n\n  get isUserDefined() {\n    return this.__isUserDefined;\n  }\n\n  set isUserDefined(val) {\n    this.__isUserDefined = val;\n  }\n\n  get addedInsideCallback() {\n    return this.__addedInsideCallback;\n  }\n\n  set addedInsideCallback(val) {\n    this.__addedInsideCallback = val;\n  }\n\n  set ignoreUnderscoreLeadingNames(val) {\n    this.__ignoreUnderscoreNames = val;\n  }\n\n  get ignoreUnderscoreLeadingNames() {\n    return this.__ignoreUnderscoreNames && !this.isUserDefined;\n  }\n\n  constructor(nightwatchInstance) {\n    super();\n\n    BaseLoader.lastDeferred = null;\n    this.nightwatchInstance = nightwatchInstance;\n  }\n\n  isTypescriptDisabled() {\n    return this.nightwatchInstance.settings.disable_typescript;\n  }\n\n  get settings() {\n    return this.nightwatchInstance.settings;\n  }\n\n  getTargetNamespace() {\n    return null;\n  }\n\n  isFileNameValid(fileName) {\n    if (fileName.startsWith('_') && this.ignoreUnderscoreLeadingNames) {\n      return false;\n    }\n\n    return Utils.isFileNameValid(fileName);\n  }\n\n  setNamespace(val) {\n    this.__namespace = val;\n\n    return this;\n  }\n\n  loadModule(dirPath, fileName) {\n    const fullPath = path.join(dirPath, fileName);\n    if (!this.loadSubDirectories && fs.lstatSync(fullPath).isDirectory()) {\n      return this;\n    }\n\n    this.requireModule(fullPath, fileName);\n\n    return this;\n  }\n\n  requireModule(fullPath, fileName) {\n    if (!this.isFileNameValid(fileName)) {\n      return this;\n    }\n\n    if (this.isTypescriptDisabled() && Utils.isTsFile(fileName)) {\n      return this;\n    }\n\n    this.commandName = path.parse(fullPath).name;\n    this.fileName = fullPath;\n\n    try {\n      this.module = Utils.requireModule(fullPath);\n    } catch (err) {\n      BaseLoader.handleModuleError(err, fullPath);\n    }\n  }\n\n  async loadModuleAsync(dirPath, fileName) {\n    const fullPath = path.join(dirPath, fileName);\n    if (!this.loadSubDirectories && fs.lstatSync(fullPath).isDirectory()) {\n      return this;\n    }\n\n    await this.requireModuleAsync(fullPath, fileName);\n  }\n\n  async requireModuleAsync(fullPath, fileName) {\n    if (!this.isFileNameValid(fileName)) {\n      return this;\n    }\n\n    if (this.isTypescriptDisabled() && Utils.isTsFile(fileName)) {\n      return this;\n    }\n\n    this.commandName = path.parse(fullPath).name;\n    this.fileName = fullPath;\n\n    try {\n      this.module = await Utils.requireModule(fullPath);\n    } catch (err) {\n      BaseLoader.handleModuleError(err, fullPath);\n    }\n  }\n\n  validateMethod() {}\n\n  defineArgs(parent, namespacedApi) {\n    const {commandName} = this;\n\n    const commandFn = this.commandFn.bind(this);\n    let stringifiedNamespace;\n    let mainNamespace;\n    let apiToReturn;\n\n    if (this.namespace && Utils.isString(this.namespace)) {\n      stringifiedNamespace = this.namespace;\n      mainNamespace = this.namespace;\n    } else if (Array.isArray(this.namespace) && this.namespace.length > 0) {\n      stringifiedNamespace = this.namespace.join('.');\n      mainNamespace = this.namespace[0];\n    }\n\n    if (namespacedApi && mainNamespace) {\n      namespacedApi[mainNamespace] = namespacedApi[mainNamespace] || {};\n      apiToReturn = new Proxy(namespacedApi[mainNamespace], {\n        get(_, name) {\n          // namespacedApi[mainNamespace] may change after API loading is finished.\n          return namespacedApi[mainNamespace][name];\n        }\n      });\n    } else if (parent && parent.__is_page_object_cache) {\n      // commands loaded onto a page object should return the page object only.\n      apiToReturn = parent;\n    }\n\n    const args = [\n      this.createQueuedCommandFn({\n        parent,\n        commandName,\n        namespace: stringifiedNamespace,\n        commandFn,\n        apiToReturn,\n        context: this\n      })\n    ];\n\n    // Define the element method as a namespace.\n    if (commandName in BaseLoader.commandOverrides) {\n      args[0] = BaseLoader.commandOverrides[commandName](this.nightwatchInstance, ...args);\n    }\n\n    const namespace = this.getTargetNamespace(parent, namespacedApi);\n    if (namespace) {\n      args.unshift(namespace);\n    }\n\n    return args;\n  }\n\n  getNamespacedAliases() {\n    const nsAliases = this.module && this.module.namespacedAliases;\n\n    if (nsAliases && Utils.isString(nsAliases)) {\n      return [nsAliases.split('.')];\n    }\n\n    if (Array.isArray(nsAliases)) {\n      return nsAliases\n        .filter((nsAlias) => nsAlias && Utils.isString(nsAlias))\n        .map((nsAlias) => nsAlias.split('.'));\n    }\n\n    return [];\n  }\n\n  define(parent = null) {\n    if (!this.commandFn) {\n      return this;\n    }\n\n    const {commandName, namespace, nightwatchInstance} = this;\n\n    this.validateMethod(parent);\n    const args = this.defineArgs(parent);\n    nightwatchInstance.setApiMethod(commandName, ...args);\n\n    // check for namespaced aliases\n    const nsAliases = this.getNamespacedAliases();\n    nsAliases.forEach((ns) => {\n      this.commandName = ns.pop();\n      this.setNamespace(ns);\n\n      this.validateMethod(parent);\n      const args = this.defineArgs(parent);\n      nightwatchInstance.setApiMethod(this.commandName, ...args);\n    });\n\n    this.commandName = commandName;\n    this.setNamespace(namespace);\n\n    return this.defineNamespacedApi(parent, namespacedApi);\n  }\n\n  defineNamespacedApi(parent) {\n    // namespaced api would have already been loaded as named exports (without parent),\n    // do not load commands again for parent (page-objects or within-context).\n    if (parent || !this.commandFn) {\n      return this;\n    }\n\n    const {commandName, namespace, nightwatchInstance} = this;\n\n    if (this.namespace && this.namespace.length) {\n      const args = this.defineArgs(parent, namespacedApi);\n      nightwatchInstance.setNamespacedApiMethod(commandName, ...args);\n    }\n\n    // check for namespaced aliases\n    const nsAliases = this.getNamespacedAliases();\n    nsAliases.forEach((ns) => {\n      this.commandName = ns.pop();\n\n      if (ns.length) {\n        this.setNamespace(ns);\n\n        const args = this.defineArgs(parent, namespacedApi);\n        nightwatchInstance.setNamespacedApiMethod(this.commandName, ...args);\n      }\n    });\n\n    this.commandName = commandName;\n    this.setNamespace(namespace);\n\n    return this;\n  }\n\n  getCommandOptions() {\n    return {};\n  }\n\n  createQueuedCommandFn({parent, commandName, namespace, commandFn, context, apiToReturn}) {\n    const {commandQueue, api, nightwatchInstance} = this;\n\n    return function queuedCommandFn(...args) {\n      const stackTrace = Utils.getOriginalStackTrace(queuedCommandFn);\n      const deferred = Utils.createPromise();\n      deferred.commandName = commandName;\n\n      // if this command was called from another async (custom) command\n      const isAsyncCommand = this.isES6Async;\n\n      const options = this.getCommandOptions();\n\n\n      if (args && args.length > 0 && Utils.isFunction(args[args.length - 1])) {\n        const callback = args.pop();\n\n        const userCallbackWrapper = (function(context) {\n\n          const proxyFn = new Proxy(callback, {\n            apply: function(target, thisArg, argumentsList) {\n              context.addedInsideCallback = true;\n\n              return target.apply(thisArg, argumentsList);\n            }\n          });\n          proxyFn.originalTarget = callback;\n\n          return  proxyFn;\n        })(this);\n\n        args.push(userCallbackWrapper);\n      }\n\n      // if this command was called from an async test case\n      let isES6Async = options.alwaysAsync || nightwatchInstance.settings.always_async_commands;\n\n      if (!isES6Async) {\n        isES6Async = Utils.isUndefined(this.isES6Async) ? (\n          nightwatchInstance.isES6AsyncTestcase || nightwatchInstance.isES6AsyncCommand\n        ) : isAsyncCommand;\n      }\n\n      if (!Utils.isUndefined(nightwatchInstance.isES6AsyncTestHook)) {\n        isES6Async = nightwatchInstance.isES6AsyncTestHook;\n      }\n\n      const node = commandQueue.add({\n        commandName,\n        commandFn,\n        context: this,\n        args,\n        stackTrace,\n        namespace,\n        options,\n        deferred,\n        isES6Async\n      });\n\n      if (this.module && this.module.autoInvoke) {\n        const result = node.execute(true);\n\n        return result;\n      }\n\n      if (isES6Async || options.alwaysAsync || node.isES6Async) {\n        BaseLoader.lastDeferred = node.deferred;\n        if (parent && parent.__pageObjectItem__) {\n          // never seem to reach here, because page-object commands are loaded\n          // in the starting itself before the actual page-objects are loaded,\n          // so `parent` here represents `__page_object_cache` and not the actual\n          // page on which command is being run.\n          Object.assign(node.deferred.promise, parent.__pageObjectItem__);\n        } else {\n          Object.assign(node.deferred.promise, apiToReturn || api);\n        }\n\n        //prevent unhandled rejection.\n        node.deferred.promise.catch(err => {\n          if (BaseLoader.lastDeferred) {\n            // TODO: check in what cases BaseLoader.lastDeferred could be set to null\n            // in between the execution of the test.\n            // issue: #4265; hint: could have something to do with custom commands.\n            BaseLoader.lastDeferred.reject(err);\n          }\n        });\n\n        if (!this.module?.returnFn) {\n          return node.deferred.promise;\n        }\n      }\n\n      if (this.module?.returnFn) {\n        return this.module.returnFn(node, apiToReturn || api);\n      }\n\n      return apiToReturn || api;\n    }.bind(context);\n  }\n\n  loadDriverCommands({commands, namespace}) {\n    commands.forEach(propertyName => {\n      const commandFn = BaseLoader.createDriverCommand(this, propertyName);\n\n      this.nightwatchInstance.setApiMethod(propertyName, namespace, (function (commandName) {\n        return this.createQueuedCommandFn({\n          commandName,\n          commandFn,\n          context: this,\n          namespace\n        });\n      }.bind(this))(propertyName));\n\n      // Add command to namespaced-api as well\n      namespacedApi[namespace] = namespacedApi[namespace] || {};\n      this.nightwatchInstance.setNamespacedApiMethod(propertyName, namespace, (function (commandName) {\n        return this.createQueuedCommandFn({\n          commandName,\n          commandFn,\n          context: this,\n          namespace,\n          apiToReturn: namespacedApi[namespace]\n        });\n      }.bind(this))(propertyName));\n    });\n  }\n}\n\nmodule.exports = BaseLoader;\n"
  },
  {
    "path": "lib/api/_loaders/_command-loader.js",
    "content": "const Element = require('../../element');\nconst BaseLoader = require('./_base-loader.js');\n\nclass BaseCommandLoader extends BaseLoader {\n  constructor(nightwatchInstance) {\n    super(nightwatchInstance);\n\n    this.type = 'command';\n    this.__namespace = null;\n    this.__module = null;\n    this.__commandName = null;\n    this.__commandFn = null;\n    this.__instance = null;\n    this.__isUserDefined = false;\n\n    this.ignoreUnderscoreLeadingNames = true;\n  }\n\n  static isTypeImplemented(instance, method, type) {\n    const methodTypes = method.split('|');\n\n    if (type === '*') {\n      return instance[method] !== undefined;\n    }\n\n    return methodTypes.some(method => (typeof instance[method] == type));\n  }\n\n  get sessionId() {\n    return this.nightwatchInstance.session.sessionId;\n  }\n\n  getCommandOptions() {\n    const redact = this.module.RedactParams || false;\n    const alwaysAsync = this.module.alwaysAsync || false;\n    const isTraceable = this.module.isTraceable;\n    const avoidPrematureParentNodeResolution = !!this.module.avoidPrematureParentNodeResolution;\n    const rejectNodeOnAbortFailure = !!this.module.rejectNodeOnAbortFailure;\n\n    return {redact, alwaysAsync, isTraceable, avoidPrematureParentNodeResolution, rejectNodeOnAbortFailure};\n  }\n\n  validateMethod(parent) {\n    let namespace = this.getTargetNamespace(parent);\n    if (Array.isArray(namespace) && namespace.length > 0) {\n      namespace = BaseLoader.unflattenNamespace(this.api, namespace.slice());\n    }\n\n    if (this.module.allowOverride) {\n      this.nightwatchInstance.overridableCommands.add(this.commandName);\n    }\n\n    if (this.nightwatchInstance.isApiMethodDefined(this.commandName, namespace) && !this.nightwatchInstance.overridableCommands.has(this.commandName)) {\n      const err = new TypeError(`Error while loading the API commands: the ${this.type} ${this.namespace || ''}.${this.commandName}() is already defined.`);\n      err.displayed = false;\n      err.detailedErr = `Source: ${this.fileName}`;\n      err.showTrace = false;\n\n      throw err;\n    }\n\n    return this;\n  }\n\n  resolveElementSelector(args) {\n    if ((args[0] instanceof Element) && this.isUserDefined) {\n      const element = args[0];\n\n      if (element.usingRecursion) {\n        return this.elementLocator.resolveElementRecursively({element});\n      }\n\n      return Promise.resolve(element);\n    }\n\n    return Promise.resolve();\n  }\n\n  getTargetNamespace(parent) {\n    const namespace = this.namespace;\n\n    if (!parent) {\n      return namespace;\n    }\n\n    if (!namespace || namespace.length === 0) {\n      return parent;\n    }\n\n    // would give unexpected results if command with nested namespaces\n    // is loaded onto say page-object (but wouldn't throw an error)\n    parent[namespace] = parent[namespace] || {};\n\n    return parent[namespace];\n  }\n}\n\nmodule.exports = BaseCommandLoader;\n"
  },
  {
    "path": "lib/api/_loaders/assertion-scheduler.js",
    "content": "const Utils = require('../../utils');\nconst Element = require('../../element');\nconst {AssertionRunner} = require('../../assertion');\nconst {Logger} = Utils;\n\nclass AssertionScheduler {\n  get instance() {\n    return this.__instance;\n  }\n\n  get opts() {\n    return this.__opts;\n  }\n\n  /**\n   * @param {AssertionInstance} instance\n   * @param {{rescheduleInterval, abortOnFailure, stackTrace, timeout, reporter}} opts\n   */\n  constructor(instance, opts = {}) {\n    this.__instance = instance;\n    this.__opts = opts;\n    this.retries = 0;\n    this.deferred = Utils.createPromise();\n    this.shouldRetry = this.opts.timeout > 0;\n    this.setOptsFromSelector();\n  }\n\n  reschedule() {\n    setTimeout(() => {\n      this.retries++;\n      this.schedule();\n    }, this.opts.rescheduleInterval);\n  }\n\n  setOptsFromSelector() {\n    if (this.instance.element instanceof Element) {\n      const {timeout, retryInterval} = this.instance.element;\n\n      if (!Utils.isUndefined(timeout)) {\n        this.__opts.timeout = timeout;\n      }\n\n      if (!Utils.isUndefined(retryInterval)) {\n        this.__opts.rescheduleInterval = retryInterval;\n      }\n    }\n  }\n\n  createAssertionRunner({passed, actual, commandCallback, message, elapsedTime}) {\n    const expected = Utils.isFunction(this.instance.expected) ? this.instance.expected() : this.instance.expected;\n    const {abortOnFailure, stackTrace, reporter} = this.opts;\n\n    this.runner = new AssertionRunner({\n      passed, err: {\n        expected,\n        actual\n      },\n      calleeFn: commandCallback,\n      message,\n      abortOnFailure,\n      stackTrace,\n      reporter,\n      elapsedTime\n    });\n  }\n\n  verifyCommandArgs() {\n    if (this.instance.command.length === 0) {\n      throw new Error(`Assertion \"command\" methods require one \"callback\" parameter. Check the command method in: ${this.instance.fileName}.`);\n    }\n\n    return this;\n  }\n\n  start() {\n    this.startTime = new Date().getTime();\n    this.schedule();\n\n    return this.deferred.promise;\n  }\n\n  schedule() {\n    this.instance.command(function commandCallback(commandResult, commandInstance) {\n      const {instance, startTime} = this;\n      const elapsedTime = new Date().getTime() - startTime;\n\n      if (commandInstance) {\n        //this.__opts.abortOnFailure = commandInstance.abortOnFailure;\n      }\n\n      let passed;\n      let value;\n      instance.elapsedTime = elapsedTime;\n      instance.setResult(commandResult);\n\n      if (instance.hasFailure()) {\n        passed = false;\n        value = null;\n      } else {\n        value = instance.getValue();\n        passed = instance.isOk(value);\n      }\n\n      if (!passed && elapsedTime < this.opts.timeout) {\n        this.reschedule();\n\n        return null;\n      }\n\n      if (instance.refineFormattedMessage) {\n        // For new generic assertions we have to create message after the actual\n        // value is resolved. Unfortunately the main formatMessage method cannot be\n        // asynchronous.\n        // I have no idea why assertion message is created before the assertion happens\n        // or at least actual value is resolved O_o\n        instance.refineFormattedMessage(value);\n      }\n\n      const message = this.getFullMessage(passed, elapsedTime);\n      const actual = instance.getActual();\n\n      this.createAssertionRunner({passed, actual, commandCallback, message, elapsedTime});\n\n      // FIXME: Returning the promise here in the event the it's needed in the assertion callback,\n      // throws an unhandledRejection when using es6 async because there's no catch in the assertion callback\n      // - adding the catch should be done when breaking changes are going to be introduced.\n\n      let resolveValue = {};\n      let testError;\n\n      if (commandResult && commandResult.error instanceof Error) {\n        testError = commandResult.error;\n      }\n\n      return this.runner\n        .run(commandResult)\n        .then(result => {\n          resolveValue = Object.assign(resolveValue, result);\n          resolveValue.passed = true;\n        })\n        .catch(err => {\n          resolveValue.passed = false;\n          resolveValue.err = err;\n\n          return err;\n        })\n        .then(() => {\n          Utils.makePromise(this.instance.doneCallback, this, [resolveValue, this.instance]);\n        })\n        .then(_ => {\n          if (testError && testError.name !== 'NoSuchElementError') {\n            this.opts.reporter.registerTestError(testError);\n          }\n          setTimeout(()=> {\n            if (resolveValue.passed) {\n              this.deferred.resolve(resolveValue);\n            } else {\n              this.deferred.reject(resolveValue.err);\n            }\n          });\n        });\n    }.bind(this), this.instance);\n  }\n\n  getFullMessage(passed, elapsedTime) {\n    if (!this.shouldRetry) {\n      return this.instance.message;\n    }\n\n    let timeLogged = passed ? elapsedTime : this.opts.timeout;\n\n    if (this.instance.message.endsWith('.')) {\n      this.instance.message = this.instance.message.substr(0, this.instance.message.length - 1);\n    }\n\n    return `${this.instance.message} ${(passed ? Logger.colors.stack_trace(`(${timeLogged}ms)`) : `in ${timeLogged}ms`)}`;\n  }\n}\n\nmodule.exports.create = function(instance, opts) {\n  const scheduler = new AssertionScheduler(instance, opts);\n  scheduler.verifyCommandArgs();\n\n  return scheduler.start();\n};\n"
  },
  {
    "path": "lib/api/_loaders/assertion.js",
    "content": "const {WebElementPromise} = require('selenium-webdriver');\n\nconst BaseCommandLoader = require('./_command-loader.js');\nconst Utils = require('../../utils');\nconst AssertionInstance = require('../assertions/_assertionInstance.js');\nconst Scheduler = require('./assertion-scheduler.js');\n\n\nclass AssertionLoader extends BaseCommandLoader {\n  static get interfaceMethods() {\n    return {\n      expected: '*',\n      'pass|evaluate': 'function',\n      command: 'function'\n    };\n  }\n\n  static validateAssertClass(instance) {\n    Object.keys(AssertionLoader.interfaceMethods).forEach(method => {\n      const type = AssertionLoader.interfaceMethods[method];\n      if (!BaseCommandLoader.isTypeImplemented(instance, method, type)) {\n        const methodTypes = method.split('|').map(name => `\"${name}\"`);\n\n        throw new Error(`Assertion class must implement method/property ${methodTypes.join(' or ')}`);\n      }\n    });\n  }\n\n  constructor(nightwatchInstance) {\n    super(nightwatchInstance);\n\n    AssertionLoader.lastDeferred = null;\n    this.type = 'assertion';\n    this.abortOnFailure = this.globals.abortOnAssertionFailure;\n  }\n\n  get timeout() {\n    return this.globals.retryAssertionTimeout;\n  }\n\n  get rescheduleInterval() {\n    return this.globals.waitForConditionPollInterval;\n  }\n\n  get globals() {\n    return this.api.globals;\n  }\n\n  containsES6Class() {\n    return this.module.prototype && this.module.prototype.constructor.toString().startsWith('class');\n  }\n\n  validateModuleDefinition() {\n    if (this.containsES6Class()) {\n      return this.validateES6Class();\n    }\n\n    return this.validateCJSModule();\n  }\n\n  validateCJSModule() {\n    if (!(Utils.isObject(this.module) && this.module.assertion)) {\n      throw new Error('The assertion module needs to contain an .assertion() method');\n    }\n  }\n\n  validateES6Class() {\n    if (!this.module.prototype.command) {\n      throw new Error('Assertion class must implement an command() method');\n    }\n  }\n\n  createQueuedCommandFn({parent, apiToReturn}) {\n    const commandFn = this.commandFn.bind(this);\n    const {commandQueue, commandName, namespace, api, nightwatchInstance} = this;\n\n    return function queuedCommandFn({negate, args}) {\n      const stackTrace = Utils.getOriginalStackTrace(queuedCommandFn);\n\n      // we only should return a Promise if not a nightwatch element, otherwise we risk breaking changes\n      const element = args[0];\n      const shouldReturnPromise = element && !(element instanceof WebElementPromise) && (element.sessionId && element.elementId || element.driver_ && element.id_);\n      const deferred = Utils.createPromise();\n      const isES6Async = shouldReturnPromise || nightwatchInstance.settings.always_async_commands ||\n        (Utils.isUndefined(this.isES6Async) ? nightwatchInstance.isES6AsyncTestcase : this.isES6Async);\n\n      const node = commandQueue.add({\n        commandName,\n        commandFn,\n        context: this,\n        args,\n        options: {\n          negate\n        },\n        stackTrace,\n        namespace,\n        deferred,\n        isES6Async\n      });\n\n      if (isES6Async) {\n        AssertionLoader.lastDeferred = deferred;\n\n        commandQueue.tree.once('asynctree:finished', (err) => {\n          node.deferred.resolve(node.resolveValue);\n        });\n\n        if (parent && parent.__pageObjectItem__) {\n          Object.assign(node.deferred.promise, parent.__pageObjectItem__);\n        } else {\n          Object.assign(node.deferred.promise, apiToReturn || api);\n        }\n\n        // prevent unhandledRejection errors\n        node.deferred.promise.catch(err => {\n          // null check, as done for BaseLoader.lastDeferred as well.\n          if (AssertionLoader.lastDeferred) {\n            return AssertionLoader.lastDeferred.reject(err);\n          }\n        });\n\n        return node.deferred.promise;\n      }\n\n      return apiToReturn || api;\n    }.bind(this);\n  }\n\n  createWrapper(abortOnFailure) {\n    if (this.module) {\n      this.validateModuleDefinition();\n      this.abortOnFailure = abortOnFailure;\n\n      this.commandFn = function commandFn({args, stackTrace, options}) {\n        return this.resolveElementSelector(args)\n          .then(elementResult => {\n            if (elementResult) {\n              args[0] = elementResult;\n            }\n\n            const {nightwatchInstance, reporter, abortOnFailure, module, fileName} = this;\n            const instance = AssertionInstance.create({\n              nightwatchInstance,\n              assertionModule: module,\n              fileName,\n              args,\n              options\n            });\n\n            AssertionLoader.validateAssertClass(instance);\n\n            this.__instance = instance;\n\n            return Scheduler.create(instance, {\n              stackTrace,\n              rescheduleInterval: Utils.isNumber(instance.rescheduleInterval) ? instance.rescheduleInterval : this.rescheduleInterval,\n              timeout: Utils.isNumber(instance.retryAssertionTimeout) ? instance.retryAssertionTimeout : this.timeout,\n              abortOnFailure,\n              reporter\n            });\n          });\n      };\n    }\n\n    return this;\n  }\n}\n\nmodule.exports = AssertionLoader;\n"
  },
  {
    "path": "lib/api/_loaders/chrome.js",
    "content": "const BaseLoader = require('./_base-loader.js');\n\nclass ChromeCommandLoader extends BaseLoader {\n  static get chromeCommands() {\n    return [\n      'launchApp',\n      'getNetworkConditions',\n      'setNetworkConditions',\n      'deleteNetworkConditions',\n      'sendDevToolsCommand',\n      'sendAndGetDevToolsCommand',\n      'setPermission',\n      'setDownloadPath',\n      'getCastSinks',\n      'setCastSinkToUse',\n      'startCastTabMirroring',\n      'getCastIssueMessage',\n      'stopCasting'\n    ];\n  }\n\n  loadCommands() {\n    const commands = ChromeCommandLoader.chromeCommands;\n\n    this.loadDriverCommands({\n      commands,\n      namespace: 'chrome'\n    });\n\n    return this;\n  }\n}\n\nmodule.exports = ChromeCommandLoader;\n"
  },
  {
    "path": "lib/api/_loaders/command.js",
    "content": "const EventEmitter = require('events');\nconst BaseCommandLoader = require('./_command-loader.js');\nconst {Logger, isES6AsyncFn, isFunction, isObject, makePromise} = require('../../utils');\n\nclass CommandLoader extends BaseCommandLoader {\n\n  static get interfaceMethods() {\n    return {\n      command: 'function'\n    };\n  }\n\n  static isDeprecatedCommandStyle(CommandModule) {\n    return isObject(CommandModule) && isFunction(CommandModule.command);\n  }\n\n  /**\n   * This is to support backwards-compatibility for commands defined as objects,\n   *  with a command() property\n   *\n   * @param CommandModule\n   */\n  static createFromObject(CommandModule) {\n    return class CommandClass extends EventEmitter {\n      command(...args) {\n        if (isES6AsyncFn(CommandModule.command)) {\n          return CommandModule.command.apply(this.api, args);\n        }\n\n        setImmediate(() => {\n          CommandModule.command.apply(this.api, args);\n        });\n\n        return this.api;\n      }\n    };\n  }\n\n  static transportActions({actions, api}) {\n    return new Proxy(actions, {\n      get(target, name) {\n        return function(...args) {\n          let callback;\n          let method;\n          const isLastArgFunction = isFunction(args[args.length - 1]);\n\n          if (isLastArgFunction) {\n            callback = args.pop();\n          } else if (args.length === 0 || !isLastArgFunction) {\n            callback = function(result) {return result};\n          }\n\n          const definition = {\n            args\n          };\n\n          if (name in target.session) { // actions that require the current session\n            method = target.session[name];\n            definition.sessionId = api.sessionId;\n          } else {\n            method = target[name];\n          }\n\n          return method(definition).then((result) => makePromise(callback, api, [result]));\n        };\n      }\n    });\n  }\n\n  static createInstance(nightwatchInstance, CommandModule, opts) {\n    const CommandClass = CommandLoader.isDeprecatedCommandStyle(CommandModule) ? CommandLoader.createFromObject(CommandModule) : CommandModule;\n\n    class CommandInstance extends CommandClass {\n      reportProtocolErrors(result) {\n        if (opts.isUserDefined) {\n          return true;\n        }\n\n        return super.reportProtocolErrors(result);\n      }\n\n      get api() {\n        return nightwatchInstance.api;\n      }\n\n      get reuseBrowser() {\n        return nightwatchInstance.argv['reuse-browser'] || (nightwatchInstance.settings.globals && nightwatchInstance.settings.globals.reuseBrowserSession);\n      }\n\n      get isES6AsyncCommand() {\n        return isES6AsyncFn(\n          CommandLoader.isDeprecatedCommandStyle(CommandModule) ? CommandModule.command : this.command\n        );\n      }\n\n      get client() {\n        return this.__nightwatchInstance || nightwatchInstance;\n      }\n\n      get commandFileName() {\n        return opts.commandName;\n      }\n\n      get commandArgs() {\n        return opts.args;\n      }\n\n      get transportActions() {\n        return this.client.transportActions;\n      }\n\n      get driver() {\n        return this.client.transport.driver;\n      }\n\n      httpRequest(requestOptions) {\n        return this.client.transport.runProtocolAction(requestOptions);\n      }\n\n      toString() {\n        return `${this.constructor.name} [name=${opts.commandName}]`;\n      }\n\n      complete(...args) {\n        if (isFunction(super.complete)) {\n          return super.complete(...args);\n        }\n\n        this.emit('complete', ...args);\n      }\n    }\n\n    const instance = new CommandInstance();\n\n    Object.keys(CommandLoader.interfaceMethods).forEach(method => {\n      const type = CommandLoader.interfaceMethods[method];\n      if (!BaseCommandLoader.isTypeImplemented(instance, method, type)) {\n        throw new Error(`Command class must implement method .${method}()`);\n      }\n    });\n\n    instance.stackTrace = opts.stackTrace;\n    instance.needsPromise = CommandLoader.isDeprecatedCommandStyle(CommandModule);\n\n    return instance;\n  }\n\n  get loadSubDirectories() {\n    return true;\n  }\n\n  createWrapper() {\n    if (this.module) {\n      // this place is only reached by client-commands, protocol commands and custom-commands (no assertions or element-commands).\n      if (this.isUserDefined) {\n        // only custom-commands will reach here.\n        // later extend this to client-commands and protocol commands as well.\n        Object.defineProperty(this.module, 'rejectNodeOnAbortFailure', {\n          configurable: true,\n          get() {\n            return true;\n          }\n        });\n      }\n\n      this.commandFn = function commandFn({args, stackTrace}) {\n        const instance = CommandLoader.createInstance(this.nightwatchInstance, this.module, {\n          stackTrace,\n          args,\n          commandName: this.commandName,\n          isUserDefined: this.isUserDefined\n        });\n\n        if (this.module.autoInvoke) {\n          this.nightwatchInstance.isES6AsyncCommand = instance.isES6AsyncCommand && this.isUserDefined;\n\n          return instance.command(...args);\n        }\n\n        if (instance.w3c_deprecated) {\n          const extraMessage = instance.deprecationNotice ? `\\n  ${instance.deprecationNotice}` : '';\n          // eslint-disable-next-line no-console\n          console.warn(`This command has been deprecated and is removed from the W3C Webdriver standard. It is only working with legacy Selenium JSONWire protocol.${extraMessage}`);\n        }\n\n        const result = this.resolveElementSelector(args)\n          .then(elementResult => {\n            if (elementResult) {\n              args[0] = elementResult;\n            }\n\n            this.nightwatchInstance.isES6AsyncCommand = instance.isES6AsyncCommand && this.isUserDefined;\n\n            return instance.command(...args);\n          })\n          .catch(err => {\n            if (instance instanceof EventEmitter) {\n              if (instance.needsPromise) {\n                // if the instance has `needsPromise` set to `true`, the `error` event is listened\n                // on the `context` object, not on the `instance` object (in `treenode.js`).\n                this.emit('error', err);\n              } else {\n                // for class-based commands that inherit from EventEmitter.\n                // Since the `needsPromise` is set to `false` in this case, the `complete` and `error`\n                // events are listened on the `instance` object.\n                instance.emit('error', err);\n              }\n\n              return;\n            }\n\n            if (!['NightwatchAssertError', 'NightwatchMountError', 'TestingLibraryError'].includes(err.name)) {\n              Logger.error(err);\n              instance.client.reporter.registerTestError(err);\n            }\n\n            return err;\n          })\n          .then(result => {\n            let reportErrors = instance.client.settings.report_command_errors;\n            const reportNetworkErrors = instance.client.settings.report_network_errors;\n\n            if (result && result.error && result.error.code && result.status === -1 && reportNetworkErrors) {\n              // node.js errors, e.g. ECONNRESET\n              reportErrors = true;\n            }\n\n            if (result && result.status === -1 && instance.reportProtocolErrors(result) && reportErrors) {\n              const err = new Error(`Error while running .${this.commandName}(): ${result.error}`);\n\n              if (result.stack) {\n                err.stack = result.stack;\n              }\n\n              if (result.error instanceof Error) {\n                result.error.registered = true;\n              } else {\n                err.registered = true;\n              }\n\n              Logger.error(err);\n              instance.client.reporter.registerTestError(err);\n            }\n\n            return result;\n          });\n\n        if (instance instanceof EventEmitter) {\n          return instance;\n        }\n\n        if (result instanceof Promise) {\n          return result;\n        }\n\n        return result;\n      };\n    }\n\n    return this;\n  }\n\n  getTargetNamespace(parent, namespacedApi) {\n    let namespace;\n    if (parent) {\n      namespace = super.getTargetNamespace(parent);\n    } else if (Array.isArray(this.namespace) && this.namespace.length > 0) {\n      namespace = BaseCommandLoader.unflattenNamespace(namespacedApi || this.api, this.namespace.slice());\n    }\n\n    return namespace;\n  }\n}\n\nmodule.exports = CommandLoader;\n"
  },
  {
    "path": "lib/api/_loaders/element-api.js",
    "content": "const {Locator} = require('../../element');\nconst Utils = require('../../utils');\nconst ScopedWebElement = require('../web-element');\nconst {By} = require('selenium-webdriver');\n\nclass ScopedElementAPILoader {\n  static get availableElementCommands() {\n    // commands directly available on `browser.element`\n    return [\n      ['findElement', 'find', 'get'],\n      ['findAll', 'findElements', 'getAll'],\n      ['findByText'],\n      ['findAllByText'],\n      ['findByRole'],\n      ['findAllByRole'],\n      ['findByAltText'],\n      ['findAllByAltText'],\n      ['findByLabelText'],\n      ['findByPlaceholderText'],\n      ['findAllByPlaceholderText']\n    ];\n  }\n\n  static isScopedElementCommand(commandName) {\n    return ScopedElementAPILoader.availableElementCommands.some(\n      commands => commands.includes(commandName)\n    );\n  }\n\n  constructor(nightwatchInstance) {\n    this.nightwatchInstance = nightwatchInstance;\n  }\n\n  createLocatingCommand(name) {\n    return Utils.setFunctionName((...args) => {\n      const rootElement = ScopedWebElement.root(this.nightwatchInstance, args);\n\n      return rootElement.createRootElementCommand(name, rootElement, args);\n    }, name);\n  }\n\n  loadElementMethods(target, element) {\n    const findActive = () => ScopedWebElement.active(this.nightwatchInstance);\n    const exportedElement = Object.assign(target, {\n      findActive,\n      getActive: findActive\n    });\n\n    ScopedElementAPILoader.availableElementCommands.forEach(commandName => {\n      let names = commandName;\n      if (!Array.isArray(names)) {\n        names = [names];\n      }\n\n      names.forEach(commandName => {\n        Object.defineProperty(exportedElement, commandName, {\n          value: this.createLocatingCommand.call(this, commandName, element),\n          writable: false\n        });\n      });\n    });\n\n    return exportedElement;\n  }\n\n  createElementMethod() {\n    const nightwatchInstance = this.nightwatchInstance;\n\n    return this.loadElementMethods(function(...args) {\n      let selector = args[0];\n\n      if (args.length >= 2 && Utils.isString(args[0]) && Utils.isString(args[1])) {\n        selector = By[Locator.AVAILABLE_LOCATORS[args[0]]](args[1]);\n      }\n\n      return ScopedWebElement.create(selector, null, nightwatchInstance);\n    });\n  }\n}\n\nmodule.exports = ScopedElementAPILoader;\n"
  },
  {
    "path": "lib/api/_loaders/element-command.js",
    "content": "const CommandLoader = require('./command.js');\nconst ElementCommand = require('../../element').Command;\n\nclass ElementCommandLoader extends CommandLoader {\n  static createInstance(CommandModule, opts) {\n    let ClassName = CommandModule || ElementCommand;\n\n    return new ClassName(opts);\n  }\n\n  createWrapper() {\n    if (this.module) {\n      this.commandFn = function commandFn({args, stackTrace}) {\n        const instance = ElementCommandLoader.createInstance(this.module, {\n          args,\n          commandName: this.commandName,\n          nightwatchInstance: this.nightwatchInstance\n        });\n\n        instance.stackTrace = stackTrace;\n\n        return instance.command();\n      };\n    }\n\n    return this;\n  }\n}\n\nmodule.exports = ElementCommandLoader;\n"
  },
  {
    "path": "lib/api/_loaders/element-global.js",
    "content": "const {until, WebElement} = require('selenium-webdriver');\nconst Utils = require('../../utils');\nconst {Logger, isUndefined, isObject, isString, isFunction} = Utils;\nconst isDefined = function(val) {\n  return !isUndefined(val);\n};\nconst Element = require('../../element');\nconst {Locator} = Element;\n\nclass ElementGlobal {\n  static get availableElementCommands() {\n    return [\n      'getId',\n      ['findElement', 'element', 'find', 'get'],\n      ['findElements', 'findAll'],\n      'click',\n      'sendKeys',\n      ['getTagName', 'tagName'],\n      ['getCssValue', 'css'],\n      ['getAttribute', 'attr', 'attribute'],\n      ['getProperty', 'property', 'prop'],\n      ['getText', 'text'],\n      ['getAriaRole', 'ariaRole'],\n      ['getAccessibleName', 'accessibleName'],\n      ['getRect', 'rect'],\n      'isEnabled',\n      'isSelected',\n      'submit',\n      'clear',\n      'isDisplayed',\n      ['takeScreenshot', 'screenshot']\n    ];\n  }\n\n  static element({locator, testSuite, client, options}) {\n    const instance = new ElementGlobal({testSuite, client, options});\n    instance.setLocator(locator);\n\n    return instance.exported();\n  }\n\n  get api() {\n    return this.nightwatchInstance.api;\n  }\n\n  get reporter() {\n    return this.nightwatchInstance.reporter;\n  }\n\n  get commandQueue() {\n    return this.nightwatchInstance.queue;\n  }\n\n  get transport() {\n    return this.nightwatchInstance.transport;\n  }\n\n  get settings() {\n    return this.client ? this.client.settings : this.testSuite.settings;\n  }\n\n  constructor({testSuite, client, options = {}}) {\n    this.testSuite = testSuite;\n    this.client = client;\n    this.isComponent = options.isComponent || false;\n    this.componentType = this.isComponent && options.type;\n    this.suppressNotFoundErrors = false;\n    this.abortOnFailure = this.settings.globals.abortOnElementLocateError;\n    this.timeout = this.settings.globals.waitForConditionTimeout;\n    this.retryInterval = this.settings.globals.waitForConditionPollInterval;\n    this.init();\n  }\n\n  init() {\n    this.nightwatchInstance = this.testSuite && this.testSuite.client ? this.testSuite.client : this.client;\n  }\n\n  async findElement() {\n    if (this.element) {\n      return;\n    }\n\n    const {locator} = this;\n    if ((locator instanceof Element) && locator.resolvedElement) {\n      this.element = this.createWebElement(locator.resolvedElement);\n\n      return;\n    }\n\n    this.element = await this.transport.driver.wait(until.elementLocated(locator), this.timeout, null, this.retryInterval);\n  }\n\n  static isElementObject(element) {\n    if (!isObject(element)) {\n      return false;\n    }\n\n    if (!isString(element.selector)) {\n      return false;\n    }\n\n    const {\n      abortOnFailure, retryInterval, timeout, suppressNotFoundErrors, index\n    } = element;\n\n    return isDefined(abortOnFailure) || isDefined(retryInterval) || isDefined(timeout) || isDefined(suppressNotFoundErrors) || isDefined(index);\n  }\n\n  setPropertiesFromElement(element) {\n    const {\n      abortOnFailure, retryInterval, timeout, suppressNotFoundErrors, index\n    } = element;\n\n    if (isDefined(index)) {\n      this.index = index;\n    }\n\n    if (isDefined(abortOnFailure)) {\n      this.abortOnFailure = abortOnFailure;\n    }\n\n    if (isDefined(suppressNotFoundErrors)) {\n      this.suppressNotFoundErrors = suppressNotFoundErrors;\n    }\n\n    if (isDefined(retryInterval)) {\n      this.retryInterval = retryInterval;\n    }\n\n    if (isDefined(timeout)) {\n      this.timeout = timeout;\n    }\n  }\n\n  createWebElement(id) {\n    return new WebElement(this.transport.driver, id);\n  }\n\n  setLocator(locator) {\n    if (WebElement.isId(locator)) {\n      this.element = this.createWebElement(WebElement.extractId(locator));\n\n      return;\n    }\n\n    if (locator instanceof WebElement) {\n      this.element = locator;\n\n      return;\n    }\n\n    if (ElementGlobal.isElementObject(locator)) {\n      locator = Element.createFromSelector(locator);\n    }\n\n    if (locator instanceof Element) {\n      this.locator = locator;\n    } else {\n      let value;\n      if (isString(locator) && this.client && this.client.locateStrategy) {\n        value = {\n          value: locator,\n          using: this.client.locateStrategy\n        };\n      } else {\n        value = locator;\n      }\n\n      this.locator = Locator.create(value);\n    }\n  }\n\n  exported() {\n    const exportedElement = Element.createFromSelector(this.locator || this.element);\n\n    this.loadCommandsOntoObject(exportedElement);\n\n    return exportedElement;\n  }\n\n  computeArguments(args, commandName) {\n    if (args.length === 0) {\n      return args;\n    }\n\n    if (['findElements', 'findElement'].includes(commandName)) {\n      if (isString(args[0])) {\n        args[0] = {\n          value: args[0],\n          using: 'css selector'\n        };\n      } else if (isObject(args[0]) && args[0].selector) {\n        if (args[0] instanceof Element || ElementGlobal.isElementObject(args[0])) {\n          this.setPropertiesFromElement(args[0]);\n        }\n\n        args[0] = Locator.create(args[0]);\n      }\n    }\n\n    return args;\n  }\n\n  getComponentProperty(propName) {\n    return this.client.transportActions.executeScript(function(property) {\n      // eslint-disable-next-line\n      if (!window['@@component_element']) {\n        throw new Error('Component was not rendered.');\n      }\n      // eslint-disable-next-line\n      if (window['@@component_element'].componentVM) {\n        // eslint-disable-next-line\n        return window['@@component_element'].componentVM[property];\n      }\n      // eslint-disable-next-line\n      return window['@@component_element'][property];\n    }, [propName]).then(result => {\n      if (result.error instanceof Error) {\n        throw result.error;\n      }\n\n      return result.value;\n    });\n  }\n\n  createCommand(commandName, commandToExecute, nightwatchName) {\n    return function executeFn(...args) {\n      const deferred = Utils.createPromise();\n      const stackTrace = Utils.getOriginalStackTrace(executeFn);\n\n      this.init();\n\n      const {api, commandQueue, nightwatchInstance} = this;\n      const commandFn = async () => {\n        const isElement = await this.setElement(stackTrace);\n        if (!isElement) {\n          return null;\n        }\n\n        if (commandName === 'findElement' && args.length === 0) {\n          return this.element;\n        }\n\n        args = this.computeArguments(args, commandName);\n        let value;\n        let error;\n\n        try {\n          if (['getProperty', 'property', 'prop'].includes(nightwatchName)  && this.isComponent && this.componentType) {\n            value = await this.getComponentProperty(args[0]);\n          } else {\n            value = await this.element[commandName].apply(this.element, args);\n          }\n        } catch (err) {\n          error = err;\n        }\n\n        if (['find', 'get', 'element'].includes(nightwatchName) && (value instanceof WebElement)) {\n          value = ElementGlobal.element({locator: value, client: nightwatchInstance});\n        } else if (nightwatchName === 'findAll') {\n          value = value.map(element => {\n            if (element instanceof WebElement) {\n              return ElementGlobal.element({locator: element, client: nightwatchInstance});\n            }\n\n            return element;\n          });\n        }\n\n        const lastArg = args[args.length - 1];\n        if (isFunction(lastArg)) {\n          if (error) {\n            return lastArg.call(this.api, {\n              value,\n              error,\n              status: 0\n            });\n          }\n\n          const callbackResult = lastArg.call(this.api, {\n            value,\n            status: 0\n          });\n\n          if (isDefined(callbackResult)) {\n            return callbackResult;\n          }\n        }\n\n        if (['find', 'get', 'element'].includes(nightwatchName) && error) {\n          return null;\n        }\n\n        if (error) {\n          throw error;\n        }\n\n        return value;\n      };\n\n      const isES6Async = true;\n      const node = commandQueue.add({\n        commandName: `element().${nightwatchName}`,\n        commandFn: commandToExecute ? commandToExecute({stackTrace}) : commandFn,\n        context: api,\n        args,\n        stackTrace,\n        namespace: null,\n        alwaysResolvePromise: true,\n        rejectPromise: true,\n        deferred,\n        isES6Async\n      });\n\n      Object.assign(node.deferred.promise, api);\n      if (commandName === 'findElement') {\n        node.deferred.promise['@nightwatch_element'] = true;\n        node.deferred.promise['@nightwatch_args'] = args;\n        if (this.isComponent) {\n          node.deferred.promise['@nightwatch_component'] = true;\n        }\n      } else if (commandName === 'findElements') {\n        node.deferred.promise['@nightwatch_multiple_elements'] = true;\n      }\n\n      return node.deferred.promise;\n    }.bind(this);\n  }\n\n  async setElement(stackTrace) {\n    try {\n      await this.findElement();\n\n      return true;\n    } catch (err) {\n      if (this.suppressNotFoundErrors) {\n        return null;\n      }\n\n      err.stack = stackTrace;\n      Logger.error(err);\n\n      if (this.abortOnFailure) {\n        this.reporter.registerTestError(err);\n      }\n\n      return null;\n    }\n  }\n\n  loadCommandsOntoObject(exportedElement) {\n    ElementGlobal.availableElementCommands.forEach(commandName => {\n      let names = commandName;\n      if (!Array.isArray(names)) {\n        names = [names];\n      }\n      const seleniumName = names[0];\n\n      names.forEach(commandName => {\n        Object.defineProperty(exportedElement, commandName, {\n          value: this.createCommand.call(this, seleniumName, null, commandName),\n          writable: false\n        });\n      });\n    });\n\n    Object.defineProperty(exportedElement, 'getWebElement', {\n      value: this.createCommand.call(this, 'getWebElement', ({stackTrace}) => {\n        return async () => {\n          const isElement = await this.setElement(stackTrace);\n          if (!isElement) {\n            return null;\n          }\n\n          return this.element;\n        };\n      }),\n      writable: false\n    });\n\n    if (this.isComponent) {\n      Object.defineProperty(exportedElement, 'isComponent', {\n        value: this.isComponent,\n        writable: false\n      });\n    }\n\n    return this;\n  }\n}\n\nmodule.exports = ElementGlobal;\n"
  },
  {
    "path": "lib/api/_loaders/ensure.js",
    "content": "const util = require('util');\nconst {until, WebElement} = require('selenium-webdriver');\nconst EventEmitter = require('events');\n\nconst Utils = require('../../utils');\nconst {AssertionRunner} = require('../../assertion');\nconst Element = require('../../element');\nconst BaseLoader = require('./_base-loader.js');\nconst {Locator} = Element;\nconst {Logger} = Utils;\n\nclass SeleniumCommand extends EventEmitter {\n  constructor({negate, args, settings, commandName}) {\n    super();\n\n    this.negate = negate;\n    this.commandName = commandName;\n    this.settings = settings;\n    this.defaultTimeout = this.settings.globals.waitForConditionTimeout;\n    this.retryInterval = this.settings.globals.waitForConditionPollInterval;\n    this.args = args;\n    this.actual = null;\n    this.message = '';\n    this.setExpected();\n  }\n\n  setExpected() {\n    let operator = this.getVerb();\n    this.expected = `${operator} '${this.args[0]}'`;\n  }\n\n  isElementCommand() {\n    return EnsureAssertionLoader.elementCommands.includes(this.commandName);\n  }\n\n  requiresLocatingElement() {\n    return EnsureAssertionLoader.requiresLocating.includes(this.commandName);\n  }\n\n  getVerb() {\n    let message = EnsureAssertionLoader.assertOperators[this.commandName];\n    let actionVerb;\n    let operator;\n\n    if (Utils.isString(message)) {\n      actionVerb = EnsureAssertionLoader.defaultVerb;\n    } else if (Array.isArray(message) && message[1]) {\n      actionVerb = message[1];\n    }\n\n    operator = this.negate ? actionVerb[1] : actionVerb[0];\n\n    return operator;\n  }\n\n  getMessage(passed) {\n    let message = EnsureAssertionLoader.assertOperators[this.commandName];\n\n    if (!message) {\n      return '';\n    }\n\n    let operator = this.getVerb();\n    if (Array.isArray(message)) {\n      message = message[0];\n    }\n\n    message = this.isElementCommand() ?\n      util.format(message, this.args[0], operator) :\n      util.format(message, operator, this.args[0]);\n\n    return message;\n  }\n\n  static isSeleniumElement(element) {\n    return (element instanceof WebElement);\n  }\n\n  async adaptElementArgument(transport) {\n    if (!this.requiresLocatingElement()) {\n      this.args[0] = Locator.create(this.args[0]);\n\n      return;\n    }\n\n    if (SeleniumCommand.isSeleniumElement(this.args[0])) {\n      return;\n    }\n\n    const locator = Locator.create(this.args[0]);\n    this.args[0] = await transport.driver.wait(until.elementLocated(locator), this.defaultTimeout);\n  }\n\n  async execute(transport) {\n    if (this.isElementCommand()) {\n      await this.adaptElementArgument(transport);\n    }\n\n    return transport.driver.wait(until[this.commandName](...this.args), this.defaultTimeout, undefined, this.retryInterval);\n  }\n}\n\nclass EnsureAssertionLoader extends BaseLoader {\n  static get defaultVerb() {\n    return ['is', 'is not'];\n  }\n\n  static get assertOperators() {\n    return {\n      ableToSwitchToFrame: 'browser driver %s able to switch to the designated frame',\n      alertIsPresent: 'alert %s present',\n      titleIs: 'title %s %s',\n      titleContains: ['title %s %s', ['contains', 'does not contain']],\n      titleMatches: ['title %s %s', ['matches', 'does not match']],\n      urlIs: 'url %s %s',\n      urlContains: ['url %s %s', ['contains', 'does not contain']],\n      urlMatches: ['url %s %s', ['matches', 'does not match']],\n      elementLocated: ['element \"%s\" %s located', ['is', 'is not']],\n      elementsLocated: ['elements \"%s\" %s located', ['are', 'are not']],\n      stalenessOf: 'element \"%s\" %s stale',\n      elementIsVisible: 'element \"%s\" %s visible',\n      elementIsNotVisible: 'element \"%s\" %s not visible',\n      elementIsEnabled: 'element \"%s\" %s enabled',\n      elementIsDisabled: 'element \"%s\" %s disabled',\n      elementIsSelected: 'element \"%s\" %s selected',\n      elementIsNotSelected: 'element \"%s\" %s not selected',\n      elementTextIs: 'element \"%s\" text %s',\n      elementTextContains: ['element \"%s\" text %s', ['contains', 'does not contain']],\n      elementTextMatches: ['element \"%s\" text %s', ['matches', 'does not match']]\n    };\n  }\n\n  static get elementCommands() {\n    return [\n      'elementLocated',\n      'elementsLocated',\n      'stalenessOf',\n      'elementIsVisible',\n      'elementIsNotVisible',\n      'elementIsEnabled',\n      'elementIsDisabled',\n      'elementIsSelected',\n      'elementIsNotSelected',\n      'elementTextIs',\n      'elementTextContains',\n      'elementTextMatches'\n    ];\n  }\n\n  static get requiresLocating() {\n    return [\n      'stalenessOf',\n      'elementIsVisible',\n      'elementIsNotVisible',\n      'elementIsEnabled',\n      'elementIsDisabled',\n      'elementIsSelected',\n      'elementIsNotSelected',\n      'elementTextIs',\n      'elementTextContains',\n      'elementTextMatches'\n    ];\n  }\n\n  async runAssertion({negate, args, commandName, abortOnFailure, assertFn}) {\n    const {reporter, transport, nightwatchInstance} = this;\n    const {settings} = nightwatchInstance;\n    const startTime = new Date();\n    const command = new SeleniumCommand({negate, args, settings, commandName});\n    const {stackTrace, expected} = command;\n    const message = command.getMessage();\n    let passed = !negate;\n    let actual = '';\n\n    try {\n      await command.execute(transport);\n    } catch (err) {\n      passed = !!negate;\n      const lines = err.message.split('\\n');\n\n      if (!negate) {\n        Logger.error(err);\n      }\n\n      if (lines.length > 1) {\n        actual = lines[1];\n      } else {\n        actual = err.message;\n      }\n\n      command.error = err;\n    }\n\n    const elapsedTime = new Date() - startTime;\n    const runner = new AssertionRunner({\n      passed,\n      err: {\n        expected, actual\n      }, message, calleeFn: assertFn, abortOnFailure, stackTrace, reporter, elapsedTime\n    });\n\n    return runner.run();\n  }\n\n  /**\n   * @param commandName\n   * @param abortOnFailure\n   * @returns {Function}\n   */\n  createAssertion(commandName, abortOnFailure) {\n    return function assertFn({negate, args}) {\n      const namespace = 'ensure';\n      const isES6Async = Utils.isUndefined(this.isES6Async) ? (this.nightwatchInstance.isES6AsyncTestcase || this.nightwatchInstance.settings.always_async_commands) : this.isES6Async;\n\n      const commandFn = () => {\n        return this.runAssertion({\n          negate,\n          args,\n          commandName,\n          abortOnFailure,\n          assertFn\n        });\n      };\n\n      const deferred = Utils.createPromise();\n      const node = this.commandQueue.add({\n        commandName: negate ? `not.${commandName}` : commandName,\n        commandFn,\n        context: this.api,\n        args: [],\n        stackTrace: assertFn.stackTrace,\n        namespace,\n        deferred,\n        isES6Async\n      });\n\n      if (isES6Async) {\n        this.commandQueue.tree.once('asynctree:finished', (err) => {\n          node.deferred.resolve();\n        });\n\n        Object.assign(node.deferred.promise, this.api);\n\n        return node.deferred.promise;\n      }\n\n      return this.api;\n    }.bind(this);\n  }\n\n  /**\n   *\n   * @param {object} [parent]\n   * @return {ApiLoader}\n   */\n  loadAssertions(parent = null) {\n    Object.keys(until).forEach(propertyName => {\n      let namespace;\n      if (parent) {\n        namespace = parent.ensure = parent.ensure || {};\n      }\n\n      this.nightwatchInstance.setApiMethod(propertyName, namespace || 'ensure', (function(commandName) {\n        return this.createAssertion(commandName, false);\n      }.bind(this))(propertyName));\n    });\n\n    return this;\n  }\n}\n\nmodule.exports = EnsureAssertionLoader;\n"
  },
  {
    "path": "lib/api/_loaders/expect-assertion.js",
    "content": "const chaiNightwatch = require('chai-nightwatch');\nconst BaseLoader = require('./_base-loader.js');\n\nclass ExpectAssertionLoader extends BaseLoader {\n  static get ChaiAssertionType() {\n    return {\n      PROPERTY: 'property',\n      METHOD: 'method'\n    };\n  }\n\n  static getChaiAssertionType(assertionType) {\n    const {PROPERTY, METHOD} = ExpectAssertionLoader.ChaiAssertionType;\n\n    switch (assertionType) {\n      case PROPERTY:\n        return 'addProperty';\n\n      case METHOD:\n        return 'addMethod';\n    }\n  }\n\n  static createMatcher({\n    assertionType,\n    commandName,\n    aliases = [],\n    nightwatchInstance,\n    AssertModule,\n    expectCommandName\n  }) {\n    if (!Array.isArray(commandName)) {\n      commandName = [commandName];\n    }\n\n    const method = ExpectAssertionLoader.getChaiAssertionType(assertionType);\n\n    commandName.forEach(command => {\n      const assertFn = function(...args) {\n        const assertion = new AssertModule({nightwatchInstance, chaiExpect: this, expectCommandName});\n\n        assertion.init(...args);\n        this.assertion = assertion;\n\n        return this;\n      };\n\n      if (!Array.isArray(aliases)) {\n        throw new Error(`Error while creating expect assertion: .aliases property needs to be an Array; received: ${aliases}`);\n      }\n\n      aliases.push(command);\n      aliases.forEach(alias => chaiNightwatch.Assertion[method](alias, assertFn));\n    });\n  }\n\n  loadAssertion(expectCommandName) {\n    if (!this.commandName) {\n      return;\n    }\n\n    const {nightwatchInstance} = this;\n    const assertionType = this.module.assertionType;\n    const commandName = this.module.assertionName || this.commandName;\n    const aliases = this.module.aliases;\n\n    ExpectAssertionLoader.createMatcher({\n      nightwatchInstance,\n      assertionType,\n      commandName,\n      expectCommandName,\n      aliases,\n      AssertModule: this.module\n    });\n  }\n}\n\nmodule.exports = ExpectAssertionLoader;\n"
  },
  {
    "path": "lib/api/_loaders/expect.js",
    "content": "const chai = require('chai-nightwatch');\nconst path = require('path');\nconst fs = require('fs');\nconst Utils = require('../../utils');\nconst BaseCommandLoader = require('./_command-loader.js');\nconst ExpectAssertionLoader = require('./expect-assertion.js');\n\nclass ExpectLoader extends BaseCommandLoader {\n  static get interfaceMethods() {\n    return {\n      command: 'function'\n    };\n  }\n\n  static createInstance(nightwatchInstance, CommandModule, opts) {\n    const commandInstance = new CommandModule({\n      nightwatchInstance,\n      commandName: opts.commandName,\n      commandArgs: opts.args\n    });\n\n    Object.keys(ExpectLoader.interfaceMethods).forEach(method => {\n      const type = ExpectLoader.interfaceMethods[method];\n      if (!BaseCommandLoader.isTypeImplemented(commandInstance, method, type)) {\n        throw new Error(`Command class must implement method .${method}()`);\n      }\n    });\n\n    return commandInstance;\n  }\n\n  createWrapper(abortOnFailure) {\n    if (this.module) {\n      this.abortOnFailure = abortOnFailure;\n      const commandName = this.commandName;\n\n      this.commandFn = function commandFn({args, stackTrace}) {\n        this.stackTrace = stackTrace;\n\n        const flagsOk = this.checkFlags();\n        if (!flagsOk) {\n          this.emit('error', new Error(`Incomplete expect assertion for \"expect.${commandName}()\". Please consult the docs at https://nightwatchjs.org/api/expect/`));\n\n          return this;\n        }\n\n        if ((args[0] instanceof Promise) && args[0]['@nightwatch_element']) {\n          let selector = '';\n\n          const elementArgs = args[0]['@nightwatch_args'] || [];\n          if (elementArgs[0] && elementArgs[0].value) {\n            selector = elementArgs[0].value;\n          }\n          args[0].then(result => {\n            args[0] = result;\n            if (!result) {\n              const err = new Error(`Unable to find element <${selector}>.`);\n              err.isExpect = true;\n              this.emit('error', err);\n\n              return this;\n            }\n\n            this.run(...args);\n          });\n        } else {\n          this.run(...args);\n        }\n\n        this.promise.catch(err => {\n          if (!(this.instance instanceof chai.Assertion)) {\n            this.emit('error', new Error(this.promiseRejectedMsg || `An error occurred while running .expect.${commandName}`));\n          }\n        });\n\n        return this;\n      };\n    }\n\n    return this;\n  }\n\n  define(parent = null) {\n    const {commandName, nightwatchInstance, commandFn, commandQueue} = this;\n    const namespace = (parent || nightwatchInstance.api).expect;\n\n    nightwatchInstance.setApiMethod(commandName, namespace, function queuedCommandFn(...args) {\n      const stackTrace = Utils.getOriginalStackTrace(queuedCommandFn);\n      const expectCommand = ExpectLoader.createInstance(nightwatchInstance, this.module, {\n        args,\n        commandName\n      });\n\n      const isAsyncCommand = this.isES6Async;\n      const isES6Async = Utils.isUndefined(this.isES6Async) ? (nightwatchInstance.isES6AsyncTestcase || nightwatchInstance.settings.always_async_commands) : isAsyncCommand;\n\n      const {deferred} = expectCommand;\n      this.loadAssertions(expectCommand);\n\n      const node = commandQueue.add({\n        commandName,\n        namespace: 'expect',\n        commandFn,\n        deferred,\n        context: expectCommand,\n        isAsyncCommand,\n        isES6Async,\n        args,\n        stackTrace\n      });\n\n      if (isES6Async && (expectCommand.instance instanceof Promise)) {\n        // prevent unhandledRejection errors\n        expectCommand.instance.catch(err => {\n          deferred.reject(err);\n        });\n      }\n\n      return expectCommand.instance;\n    }.bind(this));\n  }\n\n  loadAssertions(expectCommand) {\n    const {nightwatchInstance, commandName} = this;\n\n    // expect commands like .element() and .elements() have individual assertions (e.g. visible, present... / count);\n    // however expect commands like .url(), .title(), and .cookie only have an implicit assertion which is based on their value\n    if (expectCommand.hasAssertions) {\n      const assertionsPath = path.join(__dirname, '../expect/assertions', expectCommand.assertionsPath || commandName);\n\n      let modules = fs.readdirSync(assertionsPath);\n\n      modules = modules.filter(moduleName => {\n        return !moduleName.startsWith('_');\n      });\n\n      modules.forEach(assertionFileName => {\n        const loader = new ExpectAssertionLoader(nightwatchInstance);\n        loader\n          .loadModule(assertionsPath, assertionFileName)\n          .loadAssertion(commandName);\n      });\n    }\n  }\n\n}\n\nmodule.exports = ExpectLoader;\n"
  },
  {
    "path": "lib/api/_loaders/firefox.js",
    "content": "const BaseLoader = require('./_base-loader.js');\n\nclass FirefoxCommandLoader extends BaseLoader {\n  static get firefoxCommands() {\n    return [\n      'getContext',\n      'setContext',\n      'installAddon',\n      'uninstallAddon'\n    ];\n  }\n\n  loadCommands() {\n    const commands = FirefoxCommandLoader.firefoxCommands;\n\n    this.loadDriverCommands({\n      commands,\n      namespace: 'firefox'\n    });\n\n    return this;\n  }\n}\n\nmodule.exports = FirefoxCommandLoader;\n"
  },
  {
    "path": "lib/api/_loaders/page-object.js",
    "content": "const lodashMerge = require('lodash/merge');\nconst BaseLoader = require('./_base-loader.js');\nconst Page = require('../../page-object');\n\nlet __page_object_cache = null;\n\nclass PageObjectLoader extends BaseLoader {\n  get loadSubDirectories() {\n    return true;\n  }\n\n  get pageObjectCache() {\n    return __page_object_cache;\n  }\n\n  static loadApiCommands(nightwatchInstance) {\n    __page_object_cache = {\n      __is_page_object_cache: true\n    };\n\n    const ApiLoader = require('../index.js');\n    const StaticApis = require('./static.js');\n\n    const apiLoader = new ApiLoader(nightwatchInstance);\n    const staticApis = new StaticApis(nightwatchInstance);\n\n    staticApis.loadStaticAssertions(__page_object_cache);\n    staticApis.loadStaticExpect(__page_object_cache);\n\n    if (nightwatchInstance.startSessionEnabled) {\n      return apiLoader.loadCustomCommands(__page_object_cache)\n        .then(() => apiLoader.loadCustomAssertions(__page_object_cache))\n        .then(() => apiLoader.loadApiCommandsSync(__page_object_cache))\n        .then(() => apiLoader.loadPlugins(__page_object_cache))\n        .then(() => {\n          // TODO: possibly load .ensure assertions as well\n\n          __page_object_cache.expect.section = __page_object_cache.expect.element;\n        });\n    }\n\n    return Promise.resolve();\n  }\n\n  loadApi(pageObject) {\n    const result = lodashMerge(pageObject, this.pageObjectCache);\n\n    return result;\n  }\n\n  createWrapper() {\n    return this;\n  }\n\n  pageObjectDefinition() {\n    return new Page(this.module, this.loadApi.bind(this), this.nightwatchInstance);\n  }\n\n  define() {\n    if (this.module) {\n      const parent = this.api.page;\n      let namespace;\n      if (Array.isArray(this.namespace) && this.namespace.length > 0) {\n        namespace = BaseLoader.unflattenNamespace(parent, this.namespace.slice());\n      }\n\n      try {\n        this.module.name = this.commandName;\n        // eslint-disable-next-line\n      } catch (err) {}\n\n      this.nightwatchInstance.setApiMethod(this.commandName, namespace || 'page', this.pageObjectDefinition.bind(this));\n    }\n  }\n}\n\nmodule.exports = PageObjectLoader;\n"
  },
  {
    "path": "lib/api/_loaders/plugin.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst Utils = require('../../utils');\n\nconst __plugins = {};\n\nmodule.exports = class PluginLoader {\n\n  static get plugins() {\n    return __plugins;\n  }\n\n\n  static load(pluginName) {\n    try {\n\n      if (PluginLoader.plugins[pluginName]) {\n        return PluginLoader.plugins[pluginName];\n      }\n\n      const plugin = {};\n      const pluginPath = Utils.getPluginPath(pluginName);\n      const dirName = path.dirname(pluginPath);\n\n      plugin.instance = require(pluginPath);\n\n      let isFolder;\n      try {\n        isFolder = fs.lstatSync(path.join(dirName, 'nightwatch')).isDirectory();\n      } catch (e) {\n        plugin.hasFolder = false;\n      }\n\n      if (isFolder) {\n        // load custom commands, if any\n        const commandsFolder = path.join(dirName, 'nightwatch', 'commands');\n        try {\n          const hasCommands = fs.lstatSync(commandsFolder).isDirectory();\n          if (hasCommands) {\n            plugin.commands = commandsFolder;\n          }\n        } catch (err) {\n          plugin.commands = false;\n        }\n\n        // load custom assertions, if any\n        const assertionsFolder = path.join(dirName, 'nightwatch', 'assertions');\n        try {\n          const hasAssertions = fs.lstatSync(assertionsFolder).isDirectory();\n          if (hasAssertions) {\n            plugin.assertions = assertionsFolder;\n          }\n        } catch (err) {\n          plugin.assertions = false;\n        }\n\n        // load plugin globals, if defined\n        const globalsPath = path.join(dirName, 'nightwatch', 'globals.js');\n        plugin.globals = fs.existsSync(globalsPath) ? Utils.requireModule(globalsPath) : false;\n\n        // load plugin transforms, if defined\n        const transformsPath = path.join(dirName, 'nightwatch', 'transforms.js');\n        plugin.transforms = fs.existsSync(transformsPath) ? Utils.requireModule(transformsPath) : null;\n      }\n\n      PluginLoader.plugins[pluginName] = plugin;\n\n      return PluginLoader.plugins[pluginName];\n    } catch (err) {\n      const msg = err.message.split('\\n')[0];\n      const error = new Error(`Unable to load plugin: ${pluginName}: [${err.code}] ${msg}`);\n      error.showTrace = true;\n      error.displayed = false;\n\n      throw error;\n    }\n  }\n\n};\n"
  },
  {
    "path": "lib/api/_loaders/static.js",
    "content": "const util = require('util');\nconst chai = require('@nightwatch/chai');\nconst assertModule = require('assert');\nconst EventEmitter = require('events');\nconst Utils = require('../../utils');\nconst Element = require('../../element');\nconst chaiExpect = chai.expect;\nconst {flag} = chai.util;\nconst {AssertionRunner} = require('../../assertion');\nconst namespacedApi = require('../../core/namespaced-api.js');\n\nlet __last_deferred__ = null;\n\nmodule.exports = class StaticAssert {\n  static get assertOperators() {\n    return {\n      ok: ['ok', 'ko'],\n      equal: ['==', '!='],\n      notEqual: ['!=', '=='],\n      deepEqual: ['deepEqual', 'not deepEqual'],\n      notDeepEqual: ['not deepEqual', 'deepEqual'],\n      strictEqual: ['===', '!=='],\n      notStrictEqual: ['!==', '==='],\n      deepStrictEqual: ['deep strict equal', 'not deep strict equal'],\n      throws: ['throws', 'doesNotThrow'],\n      doesNotThrow: ['doesNotThrow', 'throws'],\n      match: ['matches', 'does not match'],\n      fail: 'fail',\n      ifError: 'ifError'\n    };\n  }\n\n  static get lastDeferred() {\n    return __last_deferred__;\n  }\n\n  static set lastDeferred(value) {\n    __last_deferred__ = value;\n  }\n\n  get api() {\n    return this.nightwatchInstance.api;\n  }\n\n  get reporter() {\n    return this.nightwatchInstance.reporter;\n  }\n\n  get commandQueue() {\n    return this.nightwatchInstance.queue;\n  }\n\n  constructor(nightwatchInstance) {\n    this.nightwatchInstance = nightwatchInstance;\n  }\n\n  /**\n   * Extends the node.js assert module\n   *\n   * @param commandName\n   * @param abortOnFailure\n   * @param apiToReturn\n   * @returns {Function}\n   */\n  createStaticAssertion(commandName, abortOnFailure, apiToReturn) {\n    class Assertion extends EventEmitter {\n      constructor({negate, args}) {\n        super();\n\n        StaticAssert.lastDeferred = null;\n        this.negate = negate;\n        this.args = args;\n        this.passed = null;\n        this.expected = null;\n        this.actual = null;\n        const lastArgument = args[args.length - 1];\n        const isLastArgString = Utils.isString(lastArgument);\n        this.message = isLastArgString && (args.length > 2 || Utils.isBoolean(args[0])) && lastArgument ||\n          Utils.isFunction(args[0]) && '[Function]';\n      }\n\n      getMessage(propName) {\n        if (!Array.isArray(StaticAssert.assertOperators[propName])) {\n          return StaticAssert.assertOperators[propName] || '';\n        }\n\n        const operator = (this.passed && !this.negate) ? StaticAssert.assertOperators[propName][0] : StaticAssert.assertOperators[propName][1];\n\n        let message = '';\n\n        if (this.negate) {\n          message += ' not ';\n        }\n\n        if (this.args.length === 2) {\n          this.args.splice(1, 0, operator);\n        } else {\n          this.args.push(operator);\n        }\n\n        this.args = this.args.map(function(argument) {\n          if (Utils.isObject(argument)) {\n            argument = util.inspect(argument);\n          }\n\n          return argument;\n        });\n\n        return message + this.args.join(' ');\n      }\n\n      assert(propName) {\n        try {\n          assertModule[propName].apply(null, this.args);\n          this.passed = !this.negate;\n          this.message = `${this.negate ? 'Failed' : 'Passed'} [${propName}]: ${this.message || this.getMessage(propName)}`;\n        } catch (ex) {\n          this.passed = !!this.negate;\n\n          if (!this.passed && (ex instanceof Error) && propName === 'fail') {\n            this.message = ex.message;\n          } else {\n            this.message = `${this.negate ? 'Passed' : 'Failed'} [${propName}]: (${ex.message || this.message || this.getMessage(propName)})`;\n          }\n\n          if (Utils.isDefined(ex.showTrace)) {\n            this.showTrace = ex.showTrace;\n          }\n\n          if (Utils.isDefined(ex.link)) {\n            this.link = ex.link;\n          }\n\n          if (Utils.isDefined(ex.help)) {\n            this.help = ex.help;\n          }\n\n          this.actual = ex.actual;\n          this.expected = ex.expected;\n          this.stackTrace = ex.stack;\n        }\n      }\n    }\n\n    return function assertFn({negate, args}) {\n      const assertion = new Assertion({negate, args});\n      const {reporter, nightwatchInstance} = this;\n      assertion.assert(commandName);\n      const startTime = new Date();\n\n      const namespace = abortOnFailure ? 'assert' : 'verify';\n      const commandFn = () => {\n        const {passed, expected, actual, message, stackTrace, showTrace, link, help} = assertion;\n        const elapsedTime = new Date() - startTime;\n\n        this.runner = new AssertionRunner({\n          passed,\n          err: {\n            expected, actual\n          }, message, calleeFn: assertFn, abortOnFailure, stackTrace, showTrace, reporter, elapsedTime, link, help\n        });\n\n        return this.runner.run();\n      };\n\n      const isES6Async = nightwatchInstance.isES6AsyncTestcase || nightwatchInstance.settings.always_async_commands;\n      const deferred = Utils.createPromise();\n\n      const node = this.commandQueue.add({\n        commandName,\n        commandFn,\n        context: this.api,\n        args: [],\n        stackTrace: assertFn.stackTrace,\n        namespace,\n        deferred,\n        isES6Async\n      });\n\n      if (isES6Async || node.isES6Async) {\n        StaticAssert.lastDeferred = deferred;\n\n        Object.assign(node.deferred.promise, apiToReturn || this.api);\n\n        //prevent unhandled rejection\n        node.deferred.promise.catch(err => {\n          return StaticAssert.lastDeferred.reject(err);\n        });\n\n        return node.deferred.promise;\n      }\n\n      return apiToReturn || this.api;\n    }.bind(this);\n  }\n\n  /**\n   *\n   * @param {object} [parent]\n   * @return {ApiLoader}\n   */\n  loadStaticAssertions(parent = null) {\n    Object.keys(assertModule).forEach(prop => {\n      let namespace;\n      if (parent) {\n        namespace = parent.assert = parent.assert || {};\n      }\n\n      let apiToReturn;\n      if (parent && parent.__is_page_object_cache) {\n        apiToReturn = parent;\n      }\n\n      const namespacedApiToReturn = (namespace) => {\n        return new Proxy(namespacedApi[namespace], {\n          get(_, name) {\n            return namespacedApi[namespace][name];\n          }\n        });\n      };\n\n      this.nightwatchInstance.setApiMethod(prop, namespace || 'assert', (function(prop) {\n        return this.createStaticAssertion(prop, true, apiToReturn);\n      }.bind(this))(prop));\n\n      if (!parent) {\n        this.nightwatchInstance.setNamespacedApiMethod(prop, 'assert', (function(prop) {\n          return this.createStaticAssertion(prop, true, namespacedApiToReturn('assert'));\n        }.bind(this))(prop));\n      }\n\n      if (this.nightwatchInstance.startSessionEnabled) {\n        let namespace;\n        if (parent) {\n          namespace = parent.verify = parent.verify || {};\n        }\n\n        this.nightwatchInstance.setApiMethod(prop, namespace || 'verify', (function(prop) {\n          return this.createStaticAssertion(prop, false);\n        }.bind(this))(prop));\n\n        if (!parent) {\n          this.nightwatchInstance.setNamespacedApiMethod(prop, 'verify', (function(prop) {\n            return this.createStaticAssertion(prop, true, namespacedApiToReturn('verify'));\n          }.bind(this))(prop));\n        }\n      }\n    });\n\n    return this;\n  }\n\n  /**\n   * @param {object} [parent]\n   */\n  loadStaticExpect(parent = null) {\n    try {\n      this.nightwatchInstance.setApiMethod('expect', parent, (...args) => {\n        let obj = args[0];\n        const isElement = Element.isElementObject(obj) || Utils.isObject(obj) && obj['@nightwatch_element'];\n\n        if (!(obj instanceof Promise) && !isElement) {\n          args[0] = obj = new Promise(resolve => resolve(obj));\n        }\n\n        const assertion = chaiExpect(...args);\n        if (!obj) {\n          return assertion;\n        }\n\n        if (isElement) {\n          if (obj.isComponent || obj['@nightwatch_component']) {\n            return this.api.expect.component(...args);\n          }\n\n          return this.api.expect.element(...args);\n        }\n\n        flag(assertion, 'actionFn', (opts) => {\n          return this.addToQueue(opts);\n        });\n\n        return assertion;\n      });\n    } catch (err) {\n      this.nightwatchInstance.setApiMethod('expect', parent, {});\n    }\n\n    return this;\n  }\n\n  addToQueue() {\n    return function assertFn(valueDisplay, assertionName, handlerFn) {\n      const abortOnFailure = true;\n      const startTime = new Date();\n      const namespace = function() {\n        return 'expect(<value>)';\n      };\n      const {nightwatchInstance, reporter} = this;\n\n      const commandFn = () => {\n        let passed = true;\n        let expected;\n        let actual;\n        let message = `Expected ${valueDisplay} ${assertionName.join(' ')}: `;\n        const stackTrace = '';\n\n        try {\n          handlerFn();\n        } catch (err) {\n          passed = false;\n          expected = err.expected;\n          actual = err.actual;\n          message = err.message;\n        }\n\n        const elapsedTime = new Date() - startTime;\n\n        this.runner = new AssertionRunner({\n          passed,\n          err: {\n            expected, actual\n          }, message, calleeFn: assertFn, abortOnFailure, stackTrace, reporter, elapsedTime\n        });\n\n        return this.runner.run();\n      };\n\n      const isES6Async = nightwatchInstance.isES6AsyncTestcase || nightwatchInstance.settings.always_async_commands;\n      const deferred = Utils.createPromise();\n\n      const node = this.commandQueue.add({\n        commandName: assertionName.join('.'),\n        commandFn,\n        context: this.api,\n        args: [],\n        stackTrace: assertFn.stackTrace,\n        namespace,\n        deferred,\n        isES6Async\n      });\n\n      if (isES6Async) {\n        Object.assign(node.deferred.promise, this.api);\n\n        return node.deferred.promise;\n      }\n\n      return this.api;\n\n    }.bind(this);\n\n  }\n};\n"
  },
  {
    "path": "lib/api/_loaders/within-context.js",
    "content": "const BaseLoader = require('./_base-loader.js');\nconst CommandWrapper = require('../../page-object/command-wrapper.js');\nconst Element = require('../../element');\n\nconst __commands_cache = {\n  __commands_cache: true\n};\n\nclass WithinLoader extends BaseLoader {\n  get loadSubDirectories() {\n    return false;\n  }\n\n  static loadCommandCache(nightwatchInstance) {\n    if (!__commands_cache.loaded) {\n      const ApiLoader = require('../index.js');\n      const apiLoader = new ApiLoader(nightwatchInstance);\n\n      return new Promise(resolve => {\n        __commands_cache.loaded = true;\n\n        if (nightwatchInstance.startSessionEnabled) {\n          return apiLoader\n            .loadCustomCommands(__commands_cache)\n            .then(() => apiLoader.initPluginTransforms())\n            .then(() => apiLoader.loadPlugins(__commands_cache))\n            .then(() => resolve());\n        }\n\n        resolve();\n      });\n\n    }\n\n    return Promise.resolve();\n  }\n\n  loadApi(context) {\n    const ApiLoader = require('../index.js');\n\n    Object.keys(__commands_cache).forEach((command) => {\n      context[command] = ((commandName) => {\n        return (...args) => {\n          return this.nightwatchInstance.api[commandName](...args);\n        };\n      })(command);\n    });\n\n    const elementCommands = ApiLoader.getElementsCommandsStrict();\n\n    if (elementCommands.length > 0) {\n      elementCommands.forEach(command => {\n        context[command] = ((commandName) => {\n          return (...args) => {\n            return this.nightwatchInstance.api[commandName](...args);\n          };\n        })(command);\n      });\n    }\n\n    return context;\n  }\n\n  createWrapper() {\n    return this;\n  }\n\n  withinDefinition(...args) {\n    if (args.length !== 1) {\n      throw new Error('within() expects exactly one argument.');\n    }\n\n    this.__instance = new WithinContext(this.loadApi.bind(this), this.nightwatchInstance, args[0]);\n\n    return this.instance;\n  }\n\n  define() {\n    this.nightwatchInstance.setApiMethod('within', this.withinDefinition.bind(this));\n  }\n}\n\nclass WithinContext {\n\n  get api() {\n    return this.__api;\n  }\n\n  get client() {\n    return this.__client;\n  }\n\n  get args() {\n    return this.__args;\n  }\n\n  constructor(loadApi, nightwatchInstance, container) {\n    this.commandLoader = loadApi;\n    this.__client = nightwatchInstance;\n    this.__api = Object.assign({}, nightwatchInstance.api);\n    this.__element = Element.createFromSelector(container);\n    this.__needsRecursion = true;\n\n    this.__promise = CommandWrapper.addWrappedCommandsAsync(this, this.commandLoader);\n  }\n}\n\nmodule.exports = WithinLoader;\n"
  },
  {
    "path": "lib/api/assertions/_assertionInstance.js",
    "content": "const util = require('util');\nconst EventEmitter = require('events');\nconst Utils = require('../../utils');\nconst Element = require('../../element');\nconst {Logger} = Utils;\n\n\nclass AssertionInstance {\n  static isElementNotFoundResult(result) {\n    if (!result) {\n      return false;\n    }\n\n    if (result.status === -1) {\n      result.value = result.value || [];\n\n      return result.value.length === 0;\n    }\n\n    return false;\n  }\n\n  static init({nightwatchInstance, args, fileName, options}) {\n    if (Utils.isFunction(args[args.length - 1])) {\n      this.__doneCallback = args.pop();\n    } else {\n      this.__doneCallback = function(result) {\n        return Promise.resolve(result);\n      };\n    }\n\n    this.__nightwatchInstance = nightwatchInstance;\n    this.__args = args;\n    this.fileName = fileName;\n    this.__negate = options.negate || false;\n    this.__commandResult = null;\n    this.retryAssertionTimeout = Utils.isObject(args[0]) ? args[0].timeout : undefined;\n    this.rescheduleInterval = Utils.isObject(args[0]) ? args[0].retryInterval : undefined;\n  }\n\n  constructor({nightwatchInstance, args, fileName, options} = {}, skipInit = false) {\n    if (!skipInit) {\n      AssertionInstance.init.call(this, {nightwatchInstance, args, fileName, options});\n      EventEmitter.prototype.constructor.call(this);\n    }\n  }\n\n  initialize() {\n    let msgReplaceArgs = this.args;\n\n    if (Utils.isFunction(this.formatMessage)) {\n      const format = this.formatMessage();\n\n      this.message = format.message;\n      if (this.message.includes('%s')) {\n        msgReplaceArgs = format.args;\n      }\n    } else {\n      msgReplaceArgs = msgReplaceArgs.map(arg => {\n        if (Utils.isObject(arg) && arg.selector) {\n          return `'<${arg.selector}>'`;\n        }\n\n        return `'${arg}'`;\n      });\n    }\n\n    if (this.message && this.message.includes('%s')) {\n      this.message = Logger.formatMessage(this.message, ...msgReplaceArgs);\n    }\n  }\n\n  set options(val) {\n    this.__options = val;\n  }\n\n  get options() {\n    return this.__options || {};\n  }\n\n  get result() {\n    return this.__commandResult;\n  }\n\n  set args(value) {\n    throw new Error(`Attempting to override \".args\" which is a reserved property in \"${this.fileName}\".`);\n  }\n\n  set elementSelector(value) {\n    throw new Error(`Attempting to override \".elementSelector\" which is a reserved property in \"${this.fileName}\".`);\n  }\n\n  set api(value) {\n    throw new Error(`Attempting to override \".api\" which is a reserved property in \"${this.fileName}\".`);\n  }\n\n  get args() {\n    return this.__args;\n  }\n\n  get negate() {\n    return this.__negate;\n  }\n\n  /**\n   * @deprecated\n   */\n  get client() {\n    return this.__nightwatchInstance.client;\n  }\n\n  get api() {\n    return this.__nightwatchInstance.api;\n  }\n\n  get doneCallback() {\n    return this.__doneCallback;\n  }\n\n  set doneCallback(value) {\n    this.__doneCallback = value;\n  }\n\n  get elementSelector() {\n    if (this.args[0] instanceof Element) {\n      return `<${this.args[0].toString()}>`;\n    }\n\n    if (Utils.isObject(this.args[0]) && this.args[0].selector) {\n      return this.args[0].selector ? `<${this.args[0].selector}>` : '';\n    }\n\n    if (Utils.isObject(this.args[0]) && this.args[0].webElementLocator) {\n      return `<${this.args[0].webElementLocator}>`;\n    }\n\n    if (this.args[0].id_ && this.args[0].driver_) {\n      return '<WebElement>';\n    }\n\n    const content = this.args[0];\n\n    return this.options.elementSelector ? `<${content}>` : `'${content}'`;\n  }\n\n  runFailure() {\n    const isFailed = this.failure(this.result);\n\n    if (isFailed && this.message.includes('%s')) {\n      this.message = Logger.formatMessage(this.message, this.args);\n    }\n\n    return isFailed;\n  }\n\n  hasFailure() {\n    if (Utils.isFunction(this.failure)) {\n      return this.runFailure();\n    }\n\n    if (!this.result || this.result.status === -1) {\n      return true;\n    }\n\n    const {error} = this.result;\n\n    return (error instanceof Error) && error.name !== 'NoSuchElementError';\n  }\n\n  getValue() {\n    if (Utils.isObject(this.result) && Utils.isUndefined(this.result.value) || this.result.status === -1) {\n      return null;\n    }\n\n    if (Utils.isFunction(this.value)) {\n      const result = this.value(this.result);\n      if (result === undefined) {\n        return null;\n      }\n\n      return result;\n    }\n\n    return this.result.value;\n  }\n\n  isOk(value = '') {\n    let passed;\n\n    // Backwards compatibility check:\n    //  if there is a \"pass\" function declared, treat it like \"evaluate\" because \"pass\"\n    //  needs to take the negate into account now\n    if (Utils.isFunction(this.pass)) {\n      passed = this.pass(value);\n    } else {\n      passed = this.evaluate(value);\n    }\n\n    return this.negate ? !passed : passed;\n  }\n\n  getActual() {\n    if (this.hasFailure()) {\n      const elementNotFound = AssertionInstance.isElementNotFoundResult(this.result);\n\n      return this.options.elementSelector ? (elementNotFound ? 'element could not be located' : 'error while locating the element') : '';\n    }\n\n    if (Utils.isFunction(this.actual)) {\n      const passed = this.evaluate(this.result.value);\n\n      return this.actual(passed);\n    }\n\n    return this.getValue();\n  }\n\n  /**\n   * @param {Object} result\n   */\n  setResult(result) {\n    this.__commandResult = result;\n  }\n\n}\n\nmodule.exports.create = function(opts = {}) {\n  const {assertionModule, nightwatchInstance = {}, fileName, args = [], options = {}} = opts;\n\n  if (assertionModule.prototype && assertionModule.prototype.constructor.toString().startsWith('class')) {\n    const err = new Error('ES6 class assertions are not supported yet.');\n    err.help = [\n      'Please use the module.exports = function() { ... } syntax instead',\n      'If you have an ESM project, you need to use the .cjs extension'\n    ];\n    err.link = 'https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html';\n\n    throw err;\n  }\n\n  const AssertionModule = Utils.isObject(assertionModule) && Utils.isFunction(assertionModule.assertion) ?\n    assertionModule.assertion :\n    assertionModule;\n\n  util.inherits(AssertionModule, EventEmitter);\n  util.inherits(AssertionInstance, AssertionModule);\n\n  const instance = new AssertionInstance({nightwatchInstance, args, fileName, options});\n  // call the assertion function\n\n  AssertionModule.prototype.constructor.apply(instance, args);\n\n  instance.initialize();\n\n  return instance;\n};\n"
  },
  {
    "path": "lib/api/assertions/attributeContains.js",
    "content": "/**\n * Checks if the given attribute of an element contains the expected value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.attributeContains('#someElement', 'href', 'google.com');\n * };\n *\n * @method assert.attributeContains\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} attribute The attribute name\n * @param {string} expected The expected contained value of the attribute to check.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, attribute, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if attribute %s of element %s ${this.negate ? 'doesn\\'t contain %s' : 'contains %s'}`;\n\n    return {\n      message,\n      args: [`'${attribute}'`, this.elementSelector, `'${expected}'`]\n    };\n  };\n\n  this.evaluate = function(value) {\n    value = value || '';\n\n    return value.includes(expected);\n  };\n\n  this.actual = function() {\n    const value = this.getValue();\n    if (typeof value != 'string') {\n      return `Element does not have a '${attribute}' attribute`;\n    }\n\n    return value;\n  };\n\n  this.expected = function() {\n    return this.negate ? `not contains '${expected}'` : `contains '${expected}'`;\n  };\n\n  this.command = function(callback) {\n    return this.api.getAttribute(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), attribute, callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/attributeEquals.js",
    "content": "/**\n * Checks if the given attribute of an element has the expected value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.attributeEquals('body', 'data-attr', 'some value');\n * };\n *\n * @method assert.attributeEquals\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} attribute The attribute name\n * @param {string} expected The expected value of the attribute to check.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, attribute, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if attribute %s of element %s ${this.negate ? 'doesn\\'t equal %s' : 'equals %s'}`;\n\n    return {\n      message,\n      args: [`'${attribute}'`, this.elementSelector, `'${expected}'`]\n    };\n  };\n\n  this.evaluate = function(value) {\n    return value === expected;\n  };\n\n  this.actual = function(passed) {\n    const value = this.getValue();\n    if (typeof value != 'string') {\n      return `Element does not have a '${attribute}' attribute`;\n    }\n\n    return value;\n  };\n\n  this.expected = function() {\n    return this.negate ? `not equals '${expected}'` : `equals '${expected}'`;\n  };\n\n  this.command = function(callback) {\n    this.api.getAttribute(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), attribute, callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/attributeMatches.js",
    "content": "/**\n * Check if an element's attribute value matches a regular expression.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.attributeMatches('body', 'data-attr', '(value)');\n * };\n *\n * @method assert.attributeMatches\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} attribute The attribute name\n * @param {string|RegExp} regexExpression Regex expression to match attribute value.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, attribute, regexExpression, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.expected = function() {\n    return this.negate ? `does not matches '${regexExpression}'` : `matches '${regexExpression}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if attribute %s of element %s ${this.negate ? 'doesn\\'t matches %s' : 'matches %s'}`;\n\n    return {\n      message,\n      args: [`'${attribute}'`, this.elementSelector, `'${regexExpression}'`]\n    };\n  };\n\n  this.evaluate = function(value) {\n    const regex = value instanceof RegExp ? value : new RegExp(regexExpression);\n\n    return regex.test(value);\n  };\n\n  this.value = function(result = {}) {\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.getAttribute(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), attribute, callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/contains.js",
    "content": "const Utils = require('../../utils/index.js');\n\nexports.assertion = function (actual, expected, message) {\n  this.options = {\n    elementSelector: false\n  };\n\n  this.expected = function () {\n    return this.negate\n      ? `does not contain ${expected}`\n      : `contains ${expected}`;\n  };\n\n  this.formatMessage = function () {\n    return {\n      args: [],\n      message: ''\n    };\n  };\n\n  this.refineFormattedMessage = function (value) {\n    const finalMessage =\n      message ||\n      `Testing if a value %s ${\n        this.negate ? 'does not contain %s' : 'contains %s'\n      }`;\n\n    this.message = finalMessage.includes('%s')\n      ? Utils.Logger.formatMessage(finalMessage, value, expected)\n      : finalMessage;\n  };\n\n  this.evaluate = function (value) {\n    return value.includes(expected);\n  };\n\n  this.command = async function (callback) {\n    return callback({value: await actual}, null);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/containsText.js",
    "content": "/**\n * Checks if the given element contains the specified text.\n *\n * ```\n *   this.demoTest = function (browser) {\n *     browser.assert.containsText('#main', 'The Night Watch');\n *   };\n * ```\n *\n * @method assert.containsText\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} expectedText The text to look for.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n * @deprecated\n */\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, expectedText, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  // eslint-disable-next-line no-console\n  console.warn('DEPRECATED: the assertion .containsText() has been deprecated and will be ' +\n    'removed from future versions. Use assert.textContains().');\n\n  /*!\n   * Returns the message format which will be used to output the message in the console and also\n   *  the arguments which will be used for replace the place holders, used in the order of appearance\n   */\n  this.formatMessage = function() {\n    const message = msg || `Testing if element %s ${this.negate ? 'does not contain text %s' : 'contains text %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${expectedText}'`]\n    };\n  };\n\n  /*!\n   * Returns the expected value of the assertion which is displayed in the case of a failure\n   *\n   * @return {string}\n   */\n  this.expected = function() {\n    return this.negate ? `does not contain text '${expectedText}'` : `contains text '${expectedText}'`;\n  };\n\n  /*!\n   * Given the value, the condition used to evaluate if the assertion is passed\n   * @param {*} value\n   * @return {Boolean}\n   */\n  this.evaluate = function(value) {\n    if (typeof value != 'string') {\n      return false;\n    }\n\n    return value.includes(expectedText);\n  };\n\n  /*!\n   * When defined, this method is called by the assertion runner with the command result, to determine if the\n   *  value can be retrieved successfully from the result object\n   *\n   * @param result\n   * @return {boolean|*}\n   */\n  this.failure = function(result) {\n    return result === false || result && result.status === -1;\n  };\n\n  /*!\n   * Called with the result object of the command to retrieve the value which is to be evaluated\n   *\n   * @param {Object} result\n   * @return {*}\n   */\n  this.value = function(result) {\n    if (result.status === -1) {\n      return null;\n    }\n\n    return result.value;\n  };\n\n  /*!\n   * When defined, this method is called by the assertion runner with the command result to determine the actual\n   *  state of the assertion in the event of a failure\n   *\n   * @param {Boolean} passed\n   * @return {string}\n   */\n  this.actual = function(passed) {\n    return passed ? `contains '${expectedText}'` : `does not contain '${expectedText}'`;\n  };\n\n  /*!\n   * The command which is to be executed by the assertion runner\n   * @param {function} callback\n   */\n  this.command = function(callback) {\n    this.api.getText(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/cssClassNotPresent.js",
    "content": "/**\n * Checks if the given element does not have the specified CSS class.\n *\n * ```\n *    this.demoTest = function (browser) {\n *      browser.assert.cssClassNotPresent('#main', 'container');\n *    };\n * ```\n *\n * @method assert.cssClassNotPresent\n * @param {string|object} definition The selector (CSS / Xpath) used to locate the element.\n * @param {string} className The CSS class to look for.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n * @deprecated\n */\nconst classListRegexp = /\\s/;\nconst classNameRegexp = /\\w/;\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, className, msg) {\n\n  this.options = {\n    elementSelector: true\n  };\n\n  // eslint-disable-next-line no-console\n  console.warn('DEPRECATED: the assertion .cssClassNotPresent() has been deprecated and will be ' +\n    'removed from future versions. Use assert.not.hasClass().');\n\n  this.formatMessage = function() {\n    let message = msg || 'Testing if element %s doesn\\'t have css class %s';\n\n    return {\n      message,\n      args: [this.elementSelector, `'${className}'`]\n    };\n  };\n\n  this.expected = function() {\n    return `has not ${className}`;\n  };\n\n  this.evaluate = function() {\n    return !this.classList.includes(className);\n  };\n\n  this.value = function(result) {\n    this.classList = result.value\n      .split(classListRegexp)\n      .filter(item => classNameRegexp.test(item));\n\n    return result.value;\n  };\n\n  this.command = function(callback) {\n    this.api.getAttribute(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), 'class', callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/cssClassPresent.js",
    "content": "/**\n * Checks if the given element has the specified CSS class. Multiple css classes can be specified either as an array or a space-delimited string.\n *\n * In case the expected value is a space delimited string, the order is not taken into account - each value will individually be checked against.\n *\n * ```\n *    this.demoTest = function (browser) {\n *      browser.assert.cssClassPresent('#main', 'container');\n *      browser.assert.cssClassPresent('#main', ['visible', 'container']);\n *      browser.assert.cssClassPresent('#main', 'visible container');\n *    };\n * ```\n *\n * @method assert.cssClassPresent\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} className The CSS class to look for.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n * @deprecated\n */\nconst classListRegexp = /\\s/;\nconst classNameRegexp = /\\w/;\nconst {containsMultiple, setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  // eslint-disable-next-line no-console\n  console.warn('DEPRECATED: the assertion .cssClassPresent() has been deprecated and will be ' +\n    'removed from future versions. Use assert.hasClass().');\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if element %s ${this.negate ? 'doesn\\'t have css class %s' : 'has css class %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${Array.isArray(expected) ? expected.join(' ') : expected}'`]\n    };\n  };\n\n  this.expected = function() {\n    return this.negate ? `has not ${expected}` : `has ${expected}`;\n  };\n\n  this.evaluate = function() {\n    if (!this.classList) {\n      return false;\n    }\n\n    return containsMultiple(this.classList, expected, ' ');\n  };\n\n  this.value = function(result) {\n    if (!result || !result.value) {\n      return '';\n    }\n\n    this.classList = result.value\n      .split(classListRegexp)\n      .filter(item => classNameRegexp.test(item));\n\n    return result.value;\n  };\n\n  this.command = function(callback) {\n    this.api.getAttribute(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), 'class', callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/cssProperty.js",
    "content": "/**\n * Checks if the specified css property of a given element has the expected value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.cssProperty('#main', 'display', 'block');\n * };\n *\n * @method assert.cssProperty\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} cssProperty The CSS property.\n * @param {string} expected The expected value of the css property to check.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, cssProperty, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if element %s ${this.negate ? 'doesn\\'t have css property %s: %s' : 'has css property %s: %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${cssProperty}`, `${expected}'`]\n    };\n  };\n\n  this.actual = function(passed) {\n    const value = this.getValue();\n    if (typeof value != 'string') {\n      return `Element does not have a '${cssProperty}' css property`;\n    }\n\n    return value;\n  };\n\n  this.expected = function() {\n    return this.negate ? `not ${expected}` : expected;\n  };\n\n  this.evaluate = function(value) {\n    return value === expected;\n  };\n\n  this.command = function(callback) {\n    this.api.getCssProperty(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), cssProperty, callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/domPropertyContains.js",
    "content": "/**\n * Checks if the specified DOM property of a given element has the expected value. For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n * Several properties can be specified (either as an array or command-separated list). Nightwatch will check each one for presence.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.domPropertyContains('#main', 'classList', 'visible');\n *\n *   // in case the resulting property is an array, several elements could be specified\n *   browser.assert.domPropertyEquals('#main', 'classList', ['class-one', 'class-two']);\n *   browser.assert.domPropertyEquals('#main', 'classList', 'class-one,class-two');\n * };\n *\n * @method assert.domPropertyContains\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} domProperty The DOM property name.\n * @param {string} expected The expected value of the DOM property to check.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nconst {formatMessage} = require('./domPropertyEquals.js');\nconst {containsMultiple, setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, domProperty, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.formatMessage = function() {\n    return formatMessage.call(this, {msg, expected, domProperty, verb(negate) {\n      return negate ? 'doesn\\'t contain %s' : 'contains %s';\n    }});\n  };\n\n  this.actual = function(passed) {\n    const value = this.getValue();\n    if (value === null) {\n      return `Element does not have a '${domProperty}' dom property`;\n    }\n\n    return value;\n  };\n\n  this.expected = function() {\n    return this.negate ? `not contains '${expected}'` : `contains '${expected}'`;\n  };\n\n  this.evaluate = function(value) {\n    if (Array.isArray(value) && expected) {\n      return containsMultiple(value, expected);\n    }\n\n    value = value || '';\n\n    return value.includes(expected);\n  };\n\n  this.command = function(callback) {\n    this.api.getElementProperty(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), domProperty, callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/domPropertyEquals.js",
    "content": "/**\n * Checks if the specified DOM property of a given element has the expected value. For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n * If the result value is JSON object or array, a deep equality comparison will be performed.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.domPropertyEquals('#main', 'className', 'visible');\n *\n *   // deep equal will be performed\n *   browser.assert.domPropertyEquals('#main', 'classList', ['class-one', 'class-two']);\n *\n *   // split on ',' and deep equal will be performed\n *   browser.assert.domPropertyEquals('#main', 'classList', 'class-one,class-two']);\n * };\n *\n * @method assert.domPropertyEquals\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} domProperty The DOM property name.\n * @param {string} expected The expected value of the DOM property to check.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nconst assert = require('assert');\nconst Utils = require('../../utils');\nconst {Logger, setElementSelectorProps} = Utils;\n\nfunction formatMsg({msg, domProperty, expected, verb = function(negate) {}}) {\n  const message = msg || `Testing if dom property %s of element %s ${verb(this.negate)}`;\n  let expectedArg = expected;\n\n  if (Utils.isObject(expected)) {\n    try {\n      expectedArg = JSON.stringify(expected);\n    } catch (e) {\n      Logger.error(e);\n      expectedArg = `[${e.name} ${e.message}]`;\n    }\n  }\n\n  return {\n    message,\n    args: [`'${domProperty}'`, this.elementSelector, `'${expectedArg}'`]\n  };\n}\n\nexports.assertion = function(definition, domProperty, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.formatMessage = function() {\n    return formatMsg.call(this, {msg, domProperty, expected, verb(negate) {\n      return negate ? 'doesn\\'t equal %s' : 'equals %s';\n    }});\n  };\n\n  this.expected = function() {\n    return this.negate ? `not ${expected}` : expected;\n  };\n\n  this.actual = function(passed) {\n    const value = this.getValue();\n    if (value === null) {\n      return `Element does not have a '${domProperty}' dom property`;\n    }\n\n    return value;\n  };\n\n  this.evaluate = function(value) {\n    if (Utils.isObject(value)) {\n      try {\n        if (Array.isArray(value) && Utils.isString(expected)) {\n          expected = expected.split(',');\n        }\n\n        // deepStrictEqual doesn't seem to catch the JSON stringify errors correctly\n        try {\n          JSON.stringify(expected);\n        } catch (e) {\n          return false;\n        }\n\n        assert.deepStrictEqual(value, expected);\n\n        return true;\n      } catch (err) {\n        return false;\n      }\n    }\n\n    return value === expected;\n  };\n\n  this.command = function(callback) {\n    this.api.getElementProperty(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), domProperty, callback);\n  };\n};\n\nexports.formatMessage = formatMsg;\n"
  },
  {
    "path": "lib/api/assertions/domPropertyMatches.js",
    "content": "/**\n * Check if specified DOM property value of a given element matches a regex. For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n *\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.domPropertyMatches('#main', 'tagName', /^frame/);\n * }\n *\n * @method assert.domPropertyMatches\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} domProperty The DOM property name.\n * @param {string|RegExp} regexExpression Regex to match against.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\n\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function (definition, domProperty, regexExpression, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.expected = function() {\n    return this.negate ? `does not matches '${regexExpression}'` : `matches '${regexExpression}'`;\n  };\n\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if dom property %s of element %s ${this.negate ? 'doesn\\'t matches %s' : 'matches %s'}`;\n\n    return {\n      message,\n      args: [`'${domProperty}'`, this.elementSelector, `'${regexExpression}'`]\n    };\n  };\n\n  this.evaluate = function (value) {\n    const regex = value instanceof RegExp ? value : new RegExp(regexExpression);\n\n    if (!Array.isArray(value)) {\n      return regex.test(value);\n    }\n\n    return false;\n  };\n\n  this.value = function(result = {}) {\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.getElementProperty(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), domProperty, callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/elementNotPresent.js",
    "content": "/**\n * Checks if the given element does not exist in the DOM.\n *\n * ```\n *    this.demoTest = function (browser) {\n *      browser.assert.elementNotPresent(\".should_not_exist\");\n *    };\n * ```\n *\n * @method assert.elementNotPresent\n * @param {string} selector The selector (CSS / Xpath) used to locate the element.\n * @param {string} [message] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n * @deprecated\n */\nconst Element = require('../../element');\n\nexports.assertion = function(selector, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  // eslint-disable-next-line no-console\n  console.warn('DEPRECATED: the assertion .elementNotPresent() has been deprecated and will be ' +\n    'removed from future versions. Use assert.not.elementPresent().');\n\n  this.element = Element.createFromSelector(selector, this.client.locateStrategy);\n  this.formatMessage = function() {\n    const message = msg || 'Testing if element %s is not present';\n\n    return {\n      message,\n      args: [this.elementSelector]\n    };\n  };\n\n  this.pass = function(value) {\n    return value === 'not present';\n  };\n\n  this.expected = function() {\n    return 'is not present';\n  };\n\n  this.value = function(result) {\n    return result.value && result.value.length > 0 ? 'present' : 'not present';\n  };\n\n  this.command = function(callback) {\n    this.api.elements(this.client.locateStrategy, this.element, callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/elementPresent.js",
    "content": "/**\n * Checks if the given element exists in the DOM.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.elementPresent(\"#main\");\n * };\n *\n * @method assert.elementPresent\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} [message] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nconst Element = require('../../element');\n\nexports.assertion = function(selector, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.element = Element.createFromSelector(selector, this.client.locateStrategy);\n  this.formatMessage = function() {\n    const message = msg || `Testing if element %s ${this.negate ? 'is not present' : 'is present'}`;\n\n    return {\n      message,\n      args: [this.elementSelector]\n    };\n  };\n\n  this.pass = function(value) {\n    return value === 'present';\n  };\n\n  this.expected = function() {\n    return this.negate ? 'is not present' : 'is present';\n  };\n\n  this.value = function(result) {\n    return result.value && result.value.length > 0 ? 'present' : 'not present';\n  };\n\n  this.command = function(callback) {\n    this.api.elements(this.client.locateStrategy, this.element, callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/elementsCount.js",
    "content": "/**\n * Checks if the number of elements specified by a selector is equal to a given value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.elementsCount('div', 10);\n *   browser.assert.not.elementsCount('div', 10);\n * }\n *\n * @method assert.elementsCount\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} count expected number of elements to be present.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\n\nconst Element = require('../../element');\n\nexports.assertion = function (definition, count, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.expected = function() {\n    return this.negate ? `does not count ${count}` : `counts ${count}`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if the element count for %s ${this.negate ? 'is not %s' : 'is %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, count]\n    };\n  };\n\n  this.evaluate = function(value) {\n    return value === count;\n  };\n\n  this.value = function(result = {}) {\n    if (!result || !result.value) {\n      return '';\n    }\n\n    return result.value.length;\n\n  };\n\n\n\n  this.command = async function(callback) {\n\n    await this.api.findElements(definition, callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/enabled.js",
    "content": "\n/**\n * Checks if the given element is enabled (as indicated by the 'disabled' attribute).\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.enabled('.should_be_enabled');\n *   browser.assert.enabled({selector: '.should_be_enabled'});\n *   browser.assert.enabled({selector: '.should_be_enabled', suppressNotFoundErrors: true});\n * };\n *\n * @method assert.enabled\n * @param {string|object} definition The selector (CSS / Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/working-with-page-objects/#element-properties).\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nexports.assertion = function(definition, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if element %s ${this.negate ? 'is not enabled' : 'is enabled'}`;\n\n    return {\n      message,\n      args: [this.elementSelector]\n    };\n  };\n\n  this.expected = function() {\n    return this.negate ? 'is not enabled' : 'is enabled';\n  };\n\n  this.evaluate = function(value) {\n    return value === true;\n  };\n\n  this.actual = function(passed) {\n    return passed ? 'enabled' : 'not enabled';\n  };\n\n  this.command = function(callback) {\n    this.api.isEnabled(definition, callback);\n  };\n\n};\n"
  },
  {
    "path": "lib/api/assertions/hasAttribute.js",
    "content": "\n/**\n * Checks if the given element contains the specified DOM attribute.\n *\n * Equivalent of: https://developer.mozilla.org/en-US/docs/Web/API/Element/hasAttribute\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.hasAttribute('#main', 'data-track');\n * };\n *\n * @method assert.hasAttribute\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} expectedAttribute The DOM attribute to look for.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\n\nconst {setElementSelectorProps, isString} = require('../../utils');\n\nexports.assertion = function(definition, expectedAttribute, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.expected = function() {\n    return this.negate ? `has not ${expectedAttribute}` : `has ${expectedAttribute}`;\n  };\n\n\n  this.formatMessage = function() {\n    if (!isString(expectedAttribute)) {\n      throw new Error('Expected attribute must be a string');\n    }\n\n    const message = msg || `Testing if element %s ${this.negate ? 'doesn\\'t have attribute %s' : 'has attribute %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${expectedAttribute}'`]\n    };\n  };\n\n  this.evaluate = function() {\n    const {result} = this;\n\n    if (!result || !result.value) {\n      return false;\n    }\n\n    return true;\n  };\n\n  this.command = function(callback) {\n    this.api.getAttribute(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), expectedAttribute, callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/hasClass.js",
    "content": "/**\n * Checks if the given element has the specified CSS class.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.hasClass('#main', 'container');\n *   browser.assert.hasClass('#main', ['visible', 'container']);\n *   browser.assert.hasClass('#main', 'visible container');\n * };\n *\n * @method hasClass\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} className The CSS class to look for.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\n\nconst classListRegexp = /\\s/;\nconst classNameRegexp = /\\w/;\nconst {containsMultiple, setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.expected = function() {\n    return this.negate ? `has not ${expected}` : `has ${expected}`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if element %s ${this.negate ? 'doesn\\'t have css class %s' : 'has css class %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${Array.isArray(expected) ? expected.join(' ') : expected}'`]\n    };\n  };\n\n\n  this.evaluate = function() {\n    if (!this.classList) {\n      return false;\n    }\n\n    return containsMultiple(this.classList, expected, ' ');\n  };\n\n  this.value = function(result) {\n    if (!result || !result.value) {\n      return '';\n    }\n\n    this.classList = result.value\n      .split(classListRegexp)\n      .filter(item => classNameRegexp.test(item));\n\n    return result.value;\n  };\n\n  this.command = function(callback) {\n    this.api.getAttribute(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), 'class', callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/hasDescendants.js",
    "content": "/**\n * Checks if the given element has child elements.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.hasDescendants('#main');\n *   browser.assert.hasDescendants('#main', 'element has child elements');\n * };\n *\n * @method assert.hasDescendants\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} className The CSS class to look for.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\n\n\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function (definition, message) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.expected = function () {\n    return `has ${this.negate ? 'not ' : ''}descendants`;\n  };\n\n  this.formatMessage = function () {\n    const finalMessage =\n      message ||\n      `Testing if an element %s has ${this.negate ? 'not ' : ''}descendants`;\n\n    return {\n      args: [this.elementSelector],\n      message: finalMessage\n    };\n  };\n\n  this.evaluate = function (value) {\n    return Boolean(value);\n  };\n\n  this.command = function (callback) {\n    this.api.hasDescendants(\n      setElementSelectorProps(definition, {\n        suppressNotFoundErrors: true\n      }),\n      callback\n    );\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/hidden.js",
    "content": "/**\n * Checks if the given element is not visible on the page.\n *\n * ```\n *    this.demoTest = function (browser) {\n *      browser.assert.hidden('.should_not_be_visible');\n *    };\n * ```\n *\n * @method hidden\n * @param {string} definition The selector (CSS / Xpath) used to locate the element.\n * @param {string} [message] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n * @deprecated\n */\nconst {setElementSelectorProps} = require('../../utils');\nconst MSG_ELEMENT_NOT_FOUND = 'Testing if element %s is hidden. ' +\n  'Element could not be located.';\n\nexports.assertion = function(definition, msg) {\n  this.expected = true;\n  this.message = msg || 'Testing if element %s is hidden.';\n\n  // eslint-disable-next-line no-console\n  console.warn('DEPRECATED: the assertion .hidden() has been deprecated and will be ' +\n    'removed from future versions. Use assert.not.visible() instead.');\n\n  this.pass = function(value) {\n    return value === this.expected;\n  };\n\n  this.failure = function(result) {\n    let failed = result === false || result && result.status === -1;\n    if (failed) {\n      this.message = msg || MSG_ELEMENT_NOT_FOUND;\n    }\n\n    return failed;\n  };\n\n  this.value = function(result) {\n    return !result.value;\n  };\n\n  this.command = function(callback) {\n    this.api.isVisible(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), callback);\n  };\n\n};\n"
  },
  {
    "path": "lib/api/assertions/promisedValue.js",
    "content": "exports.assertion = function({callback, evaluate, expected, verb, message, failure = function() {}}) {\n  this.options = {\n    elementSelector: false\n  };\n\n  this.expected = function() {\n    return this.negate ? `not ${verb} '${expected}'` : `${verb} '${expected}'`;\n  };\n\n  this.formatMessage = function() {\n    const msg = message || `Testing if element ${this.negate ? 'doesn\\'t %s' : '%s'}`;\n\n    return {\n      message: msg,\n      args: [`'${expected}'`]\n    };\n  };\n\n  this.getValue = function() {\n    return this.value;\n  };\n\n  this.failure = function() {\n    const failed = failure(expected);\n\n    if (failed) {\n      return failed.message;\n    }\n\n    return null;\n  };\n\n  this.evaluate = function(value) {\n    return evaluate(value);\n  };\n\n  this.command = function(done) {\n    callback().then((value) => {\n      this.value = value;\n      done(value);\n    }, function(error) {\n      done(error);\n    });\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/selected.js",
    "content": "\n/**\n * Checks if the given element is selected.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.selected('.should_be_selected');\n *   browser.assert.selected({selector: '.should_be_selected'});\n *   browser.assert.selected({selector: '.should_be_selected', suppressNotFoundErrors: true});\n * };\n *\n * @method assert.selected\n * @param {string|object} definition The selector (CSS / Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/working-with-page-objects/#element-properties).\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nexports.assertion = function(definition, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if element %s ${this.negate ? 'is not selected' : 'is selected'}`;\n\n    return {\n      message,\n      args: [this.elementSelector]\n    };\n  };\n\n  this.expected = function() {\n    return this.negate ? 'is not selected' : 'is selected';\n  };\n\n  this.evaluate = function(value) {\n    return value === true;\n  };\n\n  this.actual = function(passed) {\n    return passed ? 'selected' : 'not selected';\n  };\n\n  this.command = function(callback) {\n    this.api.isSelected(definition, callback);\n  };\n\n};\n"
  },
  {
    "path": "lib/api/assertions/textContains.js",
    "content": "/**\n * Checks if the given element contains the specified text.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.textContains('#main', 'The Night Watch');\n * };\n *\n * @method assert.textContains\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} expectedText The text to look for.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, expectedText, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  /*!\n   * Returns the message format which will be used to output the message in the console and also\n   *  the arguments which will be used for replace the place holders, used in the order of appearance\n   */\n  this.formatMessage = function() {\n    const message = msg || `Testing if element %s ${this.negate ? 'does not contain text %s' : 'contains text %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${expectedText}'`]\n    };\n  };\n\n  /*!\n   * Returns the expected value of the assertion which is displayed in the case of a failure\n   *\n   * @return {string}\n   */\n  this.expected = function() {\n    return this.negate ? `does not contain text '${expectedText}'` : `contains text '${expectedText}'`;\n  };\n\n  /*!\n   * Given the value, the condition used to evaluate if the assertion is passed\n   * @param {*} value\n   * @return {Boolean}\n   */\n  this.evaluate = function(value) {\n    if (typeof value != 'string') {\n      return false;\n    }\n\n    return value.includes(expectedText);\n  };\n\n  /*!\n   * When defined, this method is called by the assertion runner with the command result, to determine if the\n   *  value can be retrieved successfully from the result object\n   *\n   * @param result\n   * @return {boolean|*}\n   */\n  this.failure = function(result) {\n    return result === false || result && result.status === -1;\n  };\n\n  /*!\n   * Called with the result object of the command to retrieve the value which is to be evaluated\n   *\n   * @param {Object} result\n   * @return {*}\n   */\n  this.value = function(result) {\n    if (result.status === -1) {\n      return null;\n    }\n\n    return result.value;\n  };\n\n  /*!\n   * When defined, this method is called by the assertion runner with the command result to determine the actual\n   *  state of the assertion in the event of a failure\n   *\n   * @param {Boolean} passed\n   * @return {string}\n   */\n  this.actual = function(passed) {\n    return passed ? `contains '${expectedText}'` : `does not contain '${expectedText}'`;\n  };\n\n  /*!\n   * The command which is to be executed by the assertion runner\n   * @param {function} callback\n   */\n  this.command = function(callback) {\n    this.api.getText(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/textEquals.js",
    "content": "/**\n * Check if an element's inner text equals the expected text.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.textEquals('#main', 'The Night Watch');\n * };\n *\n * @method assert.textEquals\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} expected text to match text.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\n\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if element's %s inner text ${this.negate ? 'doesn\\'t equal %s' : 'equals %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${expected}'`]\n    };\n  };\n\n  this.expected = function() {\n    return this.negate ? `doesn't equal '${expected}'` : `equals '${expected}'`;\n  };\n\n  this.evaluate = function(value) {\n    if (typeof value != 'string') {\n      return false;\n    }\n\n    return value === expected;\n  };\n\n  this.failure = function(result) {\n    return result === false || result && result.status === -1;\n  };\n\n  this.actual = function(passed) {\n    const value = this.getValue();\n    if (typeof value != 'string') {\n      return 'Element does not have an innerText attribute';\n    }\n\n    return value;\n  };\n\n  this.value = function(result) {\n    if (result.status === -1) {\n      return null;\n    }\n\n    return result.value;\n  };\n\n  this.command = function(callback) {\n    this.api.getText(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/textMatches.js",
    "content": "/**\n * Check if an elements inner text matches a regular expression.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.textMatches('#main', '^Nightwatch');\n * };\n *\n * @method assert.textMatches\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string|RegExp} regexExpression Regex expression to match text.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\n\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, regexExpression, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.expected = function() {\n    return this.negate ? `does not matches '${regexExpression}'` : `matches '${regexExpression}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if the text ${this.negate ? 'doesn\\'t matches %s' : 'matches %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${regexExpression}'`]\n    };\n  };\n\n  this.evaluate = function(value) {\n    const regex = value instanceof RegExp ? value : new RegExp(regexExpression);\n\n    return regex.test(value);\n  };\n\n  this.value = function(result = {}) {\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.getText(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/title.js",
    "content": "/**\n * Checks if the page title equals the given value.\n *\n * ```\n *    this.demoTest = function (browser) {\n *      browser.assert.title('Nightwatch.js');\n *    };\n * ```\n *\n * @method title\n * @param {string} expected The expected page title.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n * @deprecated\n */\nexports.assertion = function(expected, msg) {\n  // eslint-disable-next-line no-console\n  console.warn('DEPRECATED: the assertion .title() has been deprecated and will be ' +\n    'removed from future versions. Use assert.titleEquals().');\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if the page title ${this.negate ? 'doesn\\'t equal %s' : 'equals %s'}`;\n\n    return {\n      message,\n      args: [`'${expected}'`]\n    };\n  };\n\n  this.expected = function() {\n    return this.negate ? `is not '${expected}'` : `is '${expected}'`;\n  };\n\n  this.pass = function(value) {\n    return value === expected;\n  };\n\n  this.value = function(result = {}) {\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.title(callback);\n  };\n\n};\n"
  },
  {
    "path": "lib/api/assertions/titleContains.js",
    "content": "/**\n * Checks if the page title contains the given value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.titleContains('Nightwatch.js');\n * };\n *\n * @method assert.titleContains\n * @param {string} value The value to look for.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nexports.assertion = function(expected, msg) {\n  this.expected = function() {\n    return this.negate ? `not contains '${expected}'` : `contains '${expected}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if the page title ${this.negate ? 'doesn\\'t contain %s' : 'contains %s'}`;\n\n    return {\n      message,\n      args: [`'${expected}'`]\n    };\n  };\n\n  this.pass = function(value) {\n    value = value || '';\n\n    return value.includes(expected);\n  };\n\n  this.value = function(result = {}) {\n    if (!result) {\n      return '';\n    }\n\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.title(callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/titleEquals.js",
    "content": "/**\n * Checks if the page title equals the given value.\n *\n * @example\n * this.demoTest = function (client) {\n *   browser.assert.titleEquals('https://www.google.com');\n * };\n *\n * @method assert.titleEquals\n * @param {string} expected The expect page title\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nexports.assertion = function(expected, msg) {\n  this.expected = function() {\n    return this.negate ? `is not '${expected}'` : `is '${expected}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if the page title ${this.negate ? 'doesn\\'t equal %s' : 'equals %s'}`;\n\n    return {\n      message,\n      args: [`'${expected}'`]\n    };\n  };\n\n  this.evaluate = function(value) {\n    return value === expected;\n  };\n\n  this.value = function(result = {}) {\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.title(callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/titleMatches.js",
    "content": "/**\n * Checks if the current title matches a regular expression.\n *\n * @example\n * this.demoTest = function (client) {\n *   browser.assert.titleMatches('^Nightwatch');\n * };\n *\n * @method assert.titleMatches\n * @param {string|RegExp} regexExpression Regex expression to match current title of a page\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nexports.assertion = function(regexExpression, msg) {\n  this.expected = function() {\n    return this.negate ? `does not matches '${regexExpression}'` : `matches '${regexExpression}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if the page title ${this.negate ? 'doesn\\'t matches %s' : 'matches %s'}`;\n\n    return {\n      message,\n      args: [`'${regexExpression}'`]\n    };\n  };\n\n  this.evaluate = function(value) {\n    const regex = value instanceof RegExp ? value : new RegExp(regexExpression);\n\n    return regex.test(value);\n  };\n\n  this.value = function(result = {}) {\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.title(callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/urlContains.js",
    "content": "/**\n * Checks if the current URL contains the given value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.urlContains('nightwatchjs.org');\n * };\n *\n * @method assert.urlContains\n * @param {string} expected The value expected to exist within the current URL.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nexports.assertion = function(expected, msg) {\n  this.expected = function() {\n    return this.negate ? `not contains '${expected}'` : `contains '${expected}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if the URL ${this.negate ? 'doesn\\'t contain %s' : 'contains %s'}`;\n\n    return {\n      message,\n      args: [`'${expected}'`]\n    };\n  };\n\n  this.pass = function(value) {\n    return value.includes(expected);\n  };\n\n  this.value = function(result = {}) {\n    if (!result) {\n      return '';\n    }\n\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.url(function(result) {\n      return callback.call(this, result);\n    });\n  };\n\n};\n"
  },
  {
    "path": "lib/api/assertions/urlEquals.js",
    "content": "/**\n * Checks if the current url equals the given value.\n *\n * @example\n * this.demoTest = function (client) {\n *   browser.assert.urlEquals('https://www.google.com');\n * };\n *\n * @method assert.urlEquals\n * @param {string} expected The expected url.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nexports.assertion = function(expected, msg) {\n  this.expected = function() {\n    return this.negate ? `is not '${expected}'` : `is '${expected}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if the URL ${this.negate ? 'is not %s' : 'is %s'}`;\n\n    return {\n      message,\n      args: [`'${expected}'`]\n    };\n  };\n\n  this.pass = function(value) {\n    return value === expected;\n  };\n\n  this.value = function(result = {}) {\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.url(callback);\n  };\n\n};\n"
  },
  {
    "path": "lib/api/assertions/urlMatches.js",
    "content": "/**\n * Checks if the current url matches a regular expression.\n *\n * @example\n * this.demoTest = function (client) {\n *   browser.assert.urlMatches('^https');\n * };\n *\n * @method assert.urlMatches\n * @param {string|RegExp} regexExpression Regex expression to match URL\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nexports.assertion = function(regexExpression, msg) {\n  this.expected = function() {\n    return this.negate ? `does not matches '${regexExpression}'` : `matches '${regexExpression}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if the URL ${this.negate ? 'doesn\\'t matches %s' : 'matches %s'}`;\n\n    return {\n      message,\n      args: [`'${regexExpression}'`]\n    };\n  };\n\n  this.evaluate = function (value) {\n    const regex = value instanceof RegExp ? value : new RegExp(regexExpression);\n\n    return regex.test(value);\n  };\n\n\n  this.value = function(result = {}) {\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.url(callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/value.js",
    "content": "/**\n * Checks if the given form element's value equals the expected value.\n *\n * ```\n *    this.demoTest = function (browser) {\n *      browser.assert.value(\"form.login input[type=text]\", \"username\");\n *    };\n * ```\n *\n * @method value\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} expected The expected text.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n * @deprecated\n */\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  // eslint-disable-next-line no-console\n  console.warn('DEPRECATED: the assertion .value() has been deprecated and will be ' +\n    'removed from future versions. Use assert.valueEquals() instead.');\n\n  this.expected = function() {\n    return this.negate ? `not equals '${expected}'` : `equals '${expected}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if value of element %s ${this.negate ? 'doesn\\'t equal %s' : 'equals %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${expected}'`]\n    };\n  };\n\n  this.actual = function(passed) {\n    const value = this.getValue();\n    if (typeof value != 'string') {\n      return 'Element does not have a value attribute';\n    }\n\n    return this.getValue();\n  };\n\n  this.evaluate = function(value) {\n    return value === expected;\n  };\n\n  this.command = function(callback) {\n    this.api.getValue(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/valueContains.js",
    "content": "/**\n * Checks if the given form element's value contains the expected value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.valueContains(\"form.login input[type=text]\", \"username\");\n * };\n *\n * @method assert.valueContains\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} expected The expected text.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.expected = function() {\n    return this.negate ? `not contains '${expected}'` : `contains '${expected}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if value of element %s ${this.negate ? 'doesn\\'t contain %s' : 'contains %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${expected}'`]\n    };\n  };\n\n  this.actual = function(passed) {\n    const value = this.getValue();\n    if (typeof value != 'string') {\n      return 'Element does not have a value attribute';\n    }\n\n    return this.getValue();\n  };\n\n  this.evaluate = function(value) {\n    value = value || '';\n\n    return value.includes(expected);\n  };\n\n  this.command = function(callback) {\n    this.api.getValue(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/valueEquals.js",
    "content": "\n/**\n * Checks if the given form element's value equals the expected value.\n *\n * The existing .assert.value() command.\n *\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.valueEquals(\"form.login input[type=text]\", \"username\");\n * };\n *\n * @method assert.valueEquals\n * @param {string|object} definition The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} expected The expected text.\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\n\nconst {setElementSelectorProps} = require('../../utils');\n\n\nexports.assertion = function(definition, expected, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.expected = function() {\n    return this.negate ? `not equals '${expected}'` : `equals '${expected}'`;\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if value of element %s ${this.negate ? 'doesn\\'t equal %s' : 'equals %s'}`;\n\n    return {\n      message,\n      args: [this.elementSelector, `'${expected}'`]\n    };\n  };\n\n  this.evaluate = function(value) {\n    return value === expected;\n  };\n\n  this.value = function(result = {}) {\n    return result.value || '';\n  };\n\n  this.command = function(callback) {\n    this.api.getValue(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/assertions/visible.js",
    "content": "/**\n * Checks if the given element is visible on the page.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.assert.visible('.should_be_visible');\n *   browser.assert.visible({selector: '.should_be_visible'});\n *   browser.assert.visible({selector: '.should_be_visible', suppressNotFoundErrors: true});\n * };\n *\n * @method assert.visible\n * @param {string|object} definition The selector (CSS / Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/working-with-page-objects/#element-properties).\n * @param {string} [msg] Optional log message to display in the output. If missing, one is displayed by default.\n * @api assertions\n */\nconst {setElementSelectorProps} = require('../../utils');\n\nexports.assertion = function(definition, msg) {\n  this.options = {\n    elementSelector: true\n  };\n\n  this.formatMessage = function() {\n    const message = msg || `Testing if element %s ${this.negate ? 'is not visible' : 'is visible'}`;\n\n    return {\n      message,\n      args: [this.elementSelector]\n    };\n  };\n\n  this.expected = function() {\n    return this.negate ? 'is not visible' : 'is visible';\n  };\n\n  this.evaluate = function(value) {\n    return value === true;\n  };\n\n  this.actual = function(passed) {\n    return passed ? 'visible' : 'not visible';\n  };\n\n  this.command = function(callback) {\n    this.api.isVisible(setElementSelectorProps(definition, {\n      suppressNotFoundErrors: true\n    }), callback);\n  };\n};\n"
  },
  {
    "path": "lib/api/client-commands/_base-command.js",
    "content": "module.exports = class ClientCommand {\n  static get isTraceable() {\n    return false;\n  }\n\n  /**\n   *\n   * @param {function} performAction Function to run which contains the command, passing a callback containing the result object\n   * @param {function} userSuppliedCallback\n   * @param {boolean} fullResultObject Weather to call the user-supplied callback with the entire result object or just the value\n   * @param {boolean} fullPromiseResolve Weather to resolve the promise with the full result object or just the \"value\" property\n   * @return {Promise}\n   */\n  static makePromise({performAction, userSuppliedCallback = function() {}, fullResultObject = true, fullPromiseResolve = true}) {\n    return new Promise(function(resolve, reject) {\n      performAction(function(result) {\n        try {\n          if (result instanceof Error) {\n            const {name, message, code} = result;\n\n            result = {\n              status: -1,\n              code,\n              name,\n              value: {\n                message\n              },\n              error: message\n            };\n          }\n\n          const resultValue = fullResultObject ? result : result.value;\n          let promise = userSuppliedCallback.call(this, resultValue);\n          if (!(promise instanceof Promise)) {\n            promise = Promise.resolve(promise);\n          }\n\n          // the final result returned in the test would be same irrespective of\n          // the value of fullPromiseResolve, thanks to `getResult` method in\n          // lib/core/treenode.js but the result value everywhere else in Nightwatch\n          // would appear to be the value of resolveValue below.\n          const resolveValue = fullPromiseResolve ? result : result.value;\n          promise.then(_ => resolve(resolveValue)).catch(err => reject(err));\n        } catch (e) {\n          reject(e);\n        }\n      });\n    });\n  }\n\n  get returnsFullResultObject() {\n    return true;\n  }\n\n  get resolvesWithFullResultObject() {\n    return true;\n  }\n\n  reportProtocolErrors(result) {\n    return true;\n  }\n\n  command(userSuppliedCallback) {\n    const {performAction} = this;\n\n    return ClientCommand.makePromise({\n      performAction: performAction.bind(this),\n      userSuppliedCallback,\n      fullResultObject: this.returnsFullResultObject,\n      fullPromiseResolve: this.resolvesWithFullResultObject\n    });\n  }\n\n  /*!\n   * Helper function for execute and execute_async\n   *\n   * @param {string} method\n   * @param {string|function} script\n   * @param {Array} args\n   * @param {function} callback\n   * @private\n   */\n  executeScriptHandler(method, script, args, callback) {\n    let fn;\n\n    if (script.originalTarget) {\n      script = script.originalTarget;\n    }\n\n    if (typeof script === 'function') {\n      fn = 'var passedArgs = Array.prototype.slice.call(arguments,0); return (' +\n        script.toString() + ').apply(window, passedArgs);';\n    } else {\n      fn = script;\n    }\n\n    return this.transportActions[method](fn, args, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/client-commands/_locateStrategy.js",
    "content": "const EventEmitter = require('events');\n\nclass Command extends EventEmitter {\n  command(callback = function() {}) {\n    this.client.setLocateStrategy(this.strategy);\n\n    process.nextTick(() => {\n      callback.call(this.api);\n\n      this.emit('complete');\n    });\n\n    return this;\n  }\n}\n\nmodule.exports = Command;\n"
  },
  {
    "path": "lib/api/client-commands/alerts/accept.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Accepts the currently displayed alert dialog. Usually, this is equivalent to clicking on the 'OK' button in the dialog.\n *\n * @example\n * module.exports = {\n *   'accept open alert': function (browser) {\n *     browser\n *       .alerts.accept(function () {\n *         console.log('alert accepted successfully');\n *       });\n *   },\n *\n *   'accept open alert with ES6 async/await': async function (browser) {\n *     await browser.alerts.accept();\n *   }\n * };\n *\n * @syntax .alerts.accept([callback])\n * @method alerts.accept\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see alerts.dismiss\n * @see alerts.getText\n * @see alerts.setText\n * @link /#accept-alert\n * @api protocol.userprompts\n */\nclass AcceptAlert extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    this.transportActions.acceptAlert(callback);\n  }\n}\n\nmodule.exports = AcceptAlert;\n"
  },
  {
    "path": "lib/api/client-commands/alerts/dismiss.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Dismisses the currently displayed alert dialog.\n *\n * For confirm() and prompt() dialogs, this is equivalent to clicking the 'Cancel' button.\n * For alert() dialogs, this is equivalent to clicking the 'OK' button.\n *\n * @example\n * module.exports = {\n *   'dismiss open alert': function (browser) {\n *     browser\n *       .alerts.dismiss(function () {\n *         console.log('alert dismissed successfully');\n *       });\n *   },\n *\n *   'dismiss open alert with ES6 async/await': async function (browser) {\n *     await browser.alerts.dismiss();\n *   }\n * };\n *\n * @syntax .alerts.dismiss([callback])\n * @method alerts.dismiss\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see alerts.accept\n * @see alerts.getText\n * @see alerts.setText\n * @link /#dismiss-alert\n * @api protocol.userprompts\n */\nclass DismissAlert extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    this.transportActions.dismissAlert(callback);\n  }\n}\n\nmodule.exports = DismissAlert;\n"
  },
  {
    "path": "lib/api/client-commands/alerts/getText.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Get the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog.\n *\n * @example\n * module.exports = {\n *   'get open alert text': function (browser) {\n *     browser\n *       .alerts.getText(function (result) {\n *         console.log('text on open alert:', result.value);\n *       });\n *   },\n *\n *   'get open alert text with ES6 async/await': async function (browser) {\n *     const alertText = await browser.alerts.getText();\n *     console.log('text on open alert:', alertText);\n *   }\n * };\n *\n * @syntax .alerts.getText([callback])\n * @method alerts.getText\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {string} The text of the currently displayed alert.\n * @see alerts.accept\n * @see alerts.dismiss\n * @see alerts.setText\n * @link /#get-alert-text\n * @api protocol.userprompts\n */\nclass GetAlertText extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.getAlertText(callback);\n  }\n}\n\nmodule.exports = GetAlertText;\n"
  },
  {
    "path": "lib/api/client-commands/alerts/setText.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Send keystrokes to a JavaScript prompt() dialog.\n *\n * @example\n * module.exports = {\n *   'set text on JS prompt': function (browser) {\n *     browser\n *       .alerts.setText('some text', function () {\n *         console.log('text sent to JS prompt successfully');\n *       });\n *   },\n *\n *   'set text on JS prompt with ES6 async/await': async function (browser) {\n *     await browser.alerts.setText('some text');\n *   }\n * };\n *\n * @syntax .alerts.setText(value, [callback])\n * @method alerts.setText\n * @param {string} value Keystrokes to send to the prompt() dialog\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see alerts.accept\n * @see alerts.dismiss\n * @see alerts.getText\n * @link /#send-alert-text\n * @api protocol.userprompts\n */\nclass SetAlertText extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    const {alertText} = this;\n\n    this.transportActions.setAlertText(alertText, callback);\n  }\n\n  command(value, callback) {\n    if (typeof value !== 'string') {\n      throw new Error('First argument passed to .alerts.setText() must be a string.');\n    }\n\n    this.alertText = value;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetAlertText;\n"
  },
  {
    "path": "lib/api/client-commands/axeInject.js",
    "content": "/**\n * Injects the [axe-core](https://github.com/dequelabs/axe-core) js library into the current page (using the `.executeScript()` command).\n *\n * To be paired with `.axeRun()` to evaluate the axe-core accessibility rules.\n *\n * @example\n * describe('accessibility testing', function () {\n *   it('accessibility rule subset', function (browser) {\n *     browser\n *       .url('https://www.w3.org/WAI/demos/bad/after/home.html')\n *       .assert.titleEquals('Welcome to CityLights! [Accessible Home Page]')\n *       .axeInject()\n *       .axeRun('body', {\n *         runOnly: ['color-contrast', 'image-alt'],\n *       });\n *   });\n * });\n *\n * @method axeInject\n * @syntax browser.axeInject()\n * @api protocol.accessibility\n * @since 2.3.6\n */\nmodule.exports = class AxeInjectAbstract {\n  static get allowOverride() {\n    return true;\n  }\n};\n"
  },
  {
    "path": "lib/api/client-commands/axeRun.js",
    "content": "/**\n * Analyzes the current page against applied axe rules.\n *\n * @example\n * describe('accessibility testing', function () {\n *   it('accessibility rule subset', function (browser) {\n *     browser\n *       .url('https://www.w3.org/WAI/demos/bad/after/home.html')\n *       .assert.titleEquals('Welcome to CityLights! [Accessible Home Page]')\n *       .axeInject()\n *       .axeRun('body', {\n *         runOnly: ['color-contrast', 'image-alt'],\n *       });\n *   });\n * });\n *\n * @method axeRun\n * @syntax browser.axeRun('body')\n * @param {any} [context] Defines the scope of the analysis, will cascade to child elements. See [axe-core docs](https://github.com/dequelabs/axe-core/blob/master/doc/API.md#context-parameter) for more details.\n * @param {object} [options] Object containing rules configuration to use when performing the analysis. See [axe-core docs](https://github.com/dequelabs/axe-core/blob/master/doc/API.md#options-parameter) for more details.\n * @param {function} [callback] Optional callback function which is called with the results.\n * @api protocol.accessibility\n * @since 2.3.6\n * @see https://www.deque.com/axe/core-documentation/api-documentation/#api-name-axerun\n */\nmodule.exports = class AxeInject {\n  static get allowOverride() {\n    return true;\n  }\n};\n"
  },
  {
    "path": "lib/api/client-commands/cookies/delete.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Delete the cookie with the given name. This command is a no-op if there is no such cookie visible to the current page.\n *\n * @example\n * module.exports = {\n *   'delete a cookie': function (browser) {\n *     browser\n *       .cookies.delete('test_cookie', function () {\n *         console.log('cookie deleted successfully');\n *       });\n *   },\n *\n *   'delete a cookie with ES6 async/await': async function (browser) {\n *     await browser.cookies.delete('test_cookie');\n *   }\n * };\n *\n * @syntax .cookies.delete(cookieName, [callback])\n * @method cookies.delete\n * @param {string} cookieName The name of the cookie to delete.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see cookies.deleteAll\n * @see cookies.get\n * @see cookies.getAll\n * @see cookies.set\n * @api protocol.cookies\n */\nclass DeleteCookie extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    const {cookieName} = this;\n\n    this.transportActions.deleteCookie(cookieName, callback);\n  }\n\n  command(cookieName, callback) {\n    if (typeof cookieName !== 'string') {\n      throw new Error('First argument passed to .cookies.delete() must be a string.');\n    }\n\n    this.cookieName = cookieName;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = DeleteCookie;\n"
  },
  {
    "path": "lib/api/client-commands/cookies/deleteAll.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Delete all cookies visible to the current page.\n *\n * @example\n * module.exports = {\n *   'delete all cookies': function (browser) {\n *     browser\n *       .cookies.deleteAll(function() {\n *         console.log('all cookies deleted successfully');\n *       });\n *   },\n *\n *   'delete all cookies with ES6 async/await': async function (browser) {\n *     await browser.cookies.deleteAll();\n *   }\n * };\n *\n * @syntax .cookies.deleteAll([callback])\n * @method cookies.deleteAll\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see cookies.delete\n * @see cookies.get\n * @see cookies.getAll\n * @see cookies.set\n * @api protocol.cookies\n */\nclass DeleteCookies extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    this.transportActions.deleteAllCookies(callback);\n  }\n}\n\nmodule.exports = DeleteCookies;\n"
  },
  {
    "path": "lib/api/client-commands/cookies/get.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Retrieve a single cookie visible to the current page.\n *\n * The cookie is returned as a cookie JSON object, with properties as defined [here](https://www.w3.org/TR/webdriver/#dfn-table-for-cookie-conversion).\n *\n * @example\n * module.exports = {\n *   'get a cookie': function (browser) {\n *     browser\n *       .cookies.get('test_cookie', function (result) {\n *         const cookie = result.value;\n *         this.assert.equal(cookie.name, 'test_cookie');\n *         this.assert.equal(cookie.value, '123456');\n *       });\n *   },\n *\n *   'get a cookie with ES6 async/await': async function (browser) {\n *     const cookie = await browser.cookies.get('test_cookie');\n *     browser.assert.equal(cookie.name, 'test_cookie');\n *     browser.assert.equal(cookie.value, '123456');\n *   }\n * };\n *\n * @syntax .cookies.get(name, [callback])\n * @method cookies.get\n * @param {string} name The cookie name.\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {object|null} The cookie object with properties as defined [here](https://www.w3.org/TR/webdriver/#dfn-table-for-cookie-conversion), or `null` if the cookie wasn't found.\n * @see cookies.getAll\n * @see cookies.set\n * @see cookies.delete\n * @see cookies.deleteAll\n * @api protocol.cookies\n */\nclass GetCookie extends ClientCommand {\n  performAction(callback) {\n    const {cookieName} = this;\n\n    this.transportActions.getCookie(cookieName, callback);\n  }\n\n  command(name, callback) {\n    if (typeof name !== 'string') {\n      throw new Error('First argument passed to .cookies.get() must be a string.');\n    }\n\n    this.cookieName = name;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = GetCookie;\n"
  },
  {
    "path": "lib/api/client-commands/cookies/getAll.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Retrieve all cookies visible to the current page.\n *\n * The cookies are returned as an array of cookie JSON object, with properties as defined [here](https://www.w3.org/TR/webdriver/#dfn-table-for-cookie-conversion).\n *\n * @example\n * module.exports = {\n *   'get all cookies': function (browser) {\n *     browser\n *       .cookies.getAll(function (result) {\n *         this.assert.equal(result.value.length, 1);\n *         this.assert.equal(result.value[0].name, 'test_cookie');\n *       });\n *   },\n *\n *   'get all cookies with ES6 async/await': async function (browser) {\n *     const cookies = await browser.cookies.getAll();\n *     browser.assert.equal(cookies.length, 1);\n *     browser.assert.equal(cookies[0].name, 'test_cookie');\n *   }\n * };\n *\n * @syntax .cookies.getAll([callback])\n * @method cookies.getAll\n * @param {function} [callback] Callback function which will receive the response as an argument.\n * @returns {Array.<object>} A list of cookie JSON objects, with properties as defined [here](https://www.w3.org/TR/webdriver/#dfn-table-for-cookie-conversion).\n * @see cookies.get\n * @see cookies.set\n * @see cookies.delete\n * @see cookies.deleteAll\n * @api protocol.cookies\n */\n\nclass GetCookies extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.getCookies(callback);\n  }\n}\n\nmodule.exports = GetCookies;\n"
  },
  {
    "path": "lib/api/client-commands/cookies/set.js",
    "content": "const ClientCommand = require('../_base-command.js');\nconst Utils = require('../../../utils/index.js');\n\n/**\n * Set a cookie, specified as a cookie JSON object, with properties as defined [here](https://www.w3.org/TR/webdriver/#dfn-table-for-cookie-conversion).\n *\n * @example\n * module.exports = {\n *   'set a cookie': function (browser) {\n *     browser\n *       .cookies.set({\n *         name: \"test_cookie\",\n *         value: \"test_value\",\n *         path: \"/\", // (Optional)\n *         domain: \"example.org\", // (Optional)\n *         secure: false, // (Optional)\n *         httpOnly: false, // (Optional)\n *         expiry: 1395002765 // (Optional) time in seconds since midnight, January 1, 1970 UTC\n *       });\n *   },\n *\n *   'set a cookie with ES6 async/await': async function (browser) {\n *     await browser.cookies.set({\n *       name: 'test_cookie',\n *       value: 'test_value',\n *       domain: 'example.org', // (Optional)\n *       sameSite: 'Lax' // (Optional)\n *     });\n *   }\n * };\n *\n * @syntax .cookies.set(cookie, [callback])\n * @method cookies.set\n * @param {object} cookie The cookie object.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see cookies.get\n * @see cookies.getAll\n * @see cookies.delete\n * @see cookies.deleteAll\n * @api protocol.cookies\n */\nclass SetCookie extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    const {cookie} = this;\n\n    this.transportActions.addCookie(cookie, callback);\n  }\n\n  command(cookie, callback) {\n    if (!Utils.isObject(cookie)) {\n      throw new Error(`First argument passed to .cookies.set() must be an object; received: ${typeof cookie} (${cookie}).`);\n    }\n\n    this.cookie = cookie;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetCookie;\n"
  },
  {
    "path": "lib/api/client-commands/debug.js",
    "content": "const EventEmitter = require('events');\nconst NightwatchRepl = require('../../testsuite/repl');\nconst Debuggability = require('../../utils/debuggability.js');\nconst {By} = require('selenium-webdriver');\n\n/**\n * This command halts the test execution and provides users with a REPL interface where they can type\n * any of the available Nightwatch commands or assertions and it will be executed in the running browser\n * in real-time.\n *\n * This can be used to debug why a certain command in not working as expected or a certain assertion is\n * failing by trying out the commands and assertions in different ways (trying an assertion with different\n * locators until the correct one if found), or just play around with the available Nightwatch commands\n * and assertions.\n *\n * You can also expose local variables and helper functions from your test to the REPL by passing\n * them via the `context` option; they will then be available in the debug prompt alongside\n * the `browser` object.\n *\n * @example\n * // async function is required while using the debug\n * // command to get the correct result as output.\n * it('demos debug command', async function (browser) {\n *   const someLocalVariable = 'something random';\n *   function someLocalFunction() {\n *     return 'local function result';\n *   }\n *\n *   // with default options\n *   browser.debug();\n *\n *   // with no auto-complete\n *   browser.debug({preview: false});\n *\n *   // with a timeout of 6000 ms (time for which the interface\n *   // would wait for a result).\n *   browser.debug({timeout: 6000});\n *\n *   // expose local variables/functions to the debug REPL\n *   browser.debug({\n *     // both values below will be directly available in the debug REPL\n *     context: {someLocalVariable, someLocalFunction}\n *   });\n * });\n *\n * @method debug\n * @param {object} [config] Config options for the REPL interface.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.utilities\n */\nclass Debug extends EventEmitter {\n  static get avoidPrematureParentNodeResolution() {\n    return true;\n  }\n\n  command(config, callback) {\n    // Create context for vm\n    const context = {\n      browser: this.api,\n      app: this.api,\n      by: By,\n      By: By\n    };\n\n    // set the user provided context\n    if (config?.context) {\n      Object.assign(context, config.context);\n      delete config.context;\n    }\n\n    const repl = new NightwatchRepl(config);\n\n    // eslint-disable-next-line\n    console.log(NightwatchRepl.introMessage());\n\n    // TODO: what's the use of this `if` block?\n    if (config?.selector) {\n      this.api.executeScript('console.log(\"Element ' + config.selector + ':\", document.querySelector(\"' + config.selector + '\"))');\n    }\n\n    // Before starting REPL server, Set debugMode to true\n    Debuggability.debugMode = true;\n\n    // Set isES6AsyncTestcase to true in debugmode\n    const isES6AsyncTestcase = this.client.isES6AsyncTestcase;\n    this.client.isES6AsyncTestcase = true;\n\n    repl.startServer(context);\n\n    repl.onExit(() => {\n      // On exit, Set debugMode to false\n      Debuggability.debugMode = false;\n      this.client.isES6AsyncTestcase = isES6AsyncTestcase;\n\n      // if we have a callback, call it right before the complete event\n      if (callback) {\n        callback.call(this.client.api);\n      }\n\n      this.emit('complete');\n    });\n\n    return this;\n  }\n}\n\nmodule.exports = Debug;\n"
  },
  {
    "path": "lib/api/client-commands/deleteCookie.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Delete the cookie with the given name. This command is a no-op if there is no such cookie visible to the current page.\n *\n * @example\n * this.demoTest = function(browser) {\n *   browser.deleteCookie(\"test_cookie\", function() {\n *     // do something more in here\n *   });\n * }\n *\n *\n * @method deleteCookie\n * @syntax .deleteCookie(cookieName, [callback])\n * @param {string} cookieName The name of the cookie to delete.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.cookies\n * @see cookie\n * @deprecated In favour of `.cookies.delete()`.\n */\nclass DeleteCookie extends ClientCommand {\n  get returnsFullResultObject() {\n    return true;\n  }\n\n  performAction(callback) {\n    this.api.cookie('DELETE', this.cookieName, callback);\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  command(cookieName, callback) {\n    this.cookieName = cookieName;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = DeleteCookie;\n"
  },
  {
    "path": "lib/api/client-commands/deleteCookies.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Delete all cookies visible to the current page.\n *\n * @example\n * this.demoTest = function(browser) {\n *   browser.deleteCookies(function() {\n *     // do something more in here\n *   });\n * }\n *\n *\n * @method deleteCookies\n * @syntax .deleteCookies([callback])\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.cookies\n * @see cookie\n * @deprecated In favour of `.cookies.deleteAll()`.\n */\nclass DeleteCookie extends ClientCommand {\n  get returnsFullResultObject() {\n    return true;\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    this.api.cookie('DELETE', callback);\n  }\n}\n\nmodule.exports = DeleteCookie;\n"
  },
  {
    "path": "lib/api/client-commands/document/executeAsyncScript.js",
    "content": "const ClientCommand = require('../_base-command.js');\nconst {isFunction} = require('../../../utils/index.js');\n\n/**\n * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be asynchronous.\n *\n * The function to be injected receives the `done` callback as argument which needs to be called when the asynchronous operation finishes. The value passed to the `done` callback is returned to the client.\n * Additional arguments for the injected function may be passed as a non-empty array which will be passed before the `done` callback.\n *\n * Asynchronous script commands may not span page loads. If an unload event is fired while waiting for the script result, an error will be returned.\n *\n * @example\n * describe('execute async script', function() {\n *   it('executes async script in browser', function(browser) {\n *     browser.executeAsyncScript(function(done) {\n *       setTimeout(function() {\n *         done(true);\n *       }, 500);\n *     }, function(result) {\n *       // whatever is passed to the `done` callback in the script above\n *       // will be available as result.value\n *       console.log(result.value); // true\n *     });\n *   });\n *\n *   it('executes a script with ES6 async/await', async function(browser) {\n *     const result = await browser\n *       .document.executeAsync(function(arg1, arg2, done) {\n *         setTimeout(function() {\n *           done(arg1);\n *         }, 500);\n *       }, [arg1, arg2]);\n *\n *     // whatever is passed to the `done` callback in the script above\n *     // will be returned by the command when used with `await`.\n *     console.log(result); // arg1\n *   });\n * });\n *\n * @method document.executeAsyncScript\n * @syntax .executeAsync(body, [args], [callback])\n * @syntax .executeAsyncScript(body, [args], [callback])\n * @syntax .document.executeAsync(body, [args], [callback])\n * @syntax .document.executeAsyncScript(body, [args], [callback])\n * @param {string|function} body The function body to be injected.\n * @param {Array} args An array of arguments which will be passed to the function.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @returns {*} The script result.\n * @see document.executeScript\n * @link /#execute-async-script\n * @api protocol.document\n */\nclass ExecuteAsyncScript extends ClientCommand {\n  static get namespacedAliases() {\n    return ['document.executeAsync', 'executeAsync', 'executeAsyncScript'];\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    const {script, scriptArgs} = this;\n\n    this.executeScriptHandler('executeAsyncScript', script, scriptArgs, callback);\n  }\n\n  command(script, args, callback) {\n    if (!script) {\n      throw new Error('First argument passed to .executeAsyncScript() must be defined.');\n    }\n\n    if (arguments.length === 1) {\n      args = [];\n    } else if (arguments.length === 2 && isFunction(arguments[1])) {\n      callback = arguments[2];\n      args = [];\n    }\n\n    this.script = script;\n    this.scriptArgs = args;\n\n    return super.command(callback);\n  }\n};\n\nmodule.exports = ExecuteAsyncScript;\n"
  },
  {
    "path": "lib/api/client-commands/document/executeScript.js",
    "content": "const ClientCommand = require('../_base-command.js');\nconst {isFunction} = require('../../../utils/index.js');\n\n/**\n * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous.\n * The script argument defines the script to execute in the form of a function body. The value returned by that function will be returned to the client.\n *\n * The function will be invoked with the provided args array and the values may be accessed via the arguments object in the order specified.\n *\n * Under the hood, if the `body` param is a function it is converted to a string with `function.toString()`. Any references to your current scope are ignored.\n *\n * To ensure cross-browser compatibility, the specified function should not be in ES6 format (i.e. `() => {}`). If the execution of the function fails, the first argument of the callback contains error information.\n *\n * @example\n * describe('execute script', function() {\n *   it('executes a script in browser', function(browser) {\n *     browser.executeScript(function(imageData) {\n *       // resize operation\n *       return true;\n *     }, [imageData], function(result) {\n *       // whatever is returned by the script passed above will be available\n *       // as result.value\n *       console.log(result.value); // true\n *     });\n *\n *     // scroll to the bottom of the page.\n *     browser.executeScript('window.scrollTo(0,document.body.scrollHeight);');\n *   });\n *\n *   it('executes a script with ES6 async/await', async function(browser) {\n *     const result = await browser\n *       .document.executeScript(function(imageData) {\n *         // resize operation\n *         return true;\n *       }, [imageData]);\n *\n *     console.log(result); // true\n *   });\n * });\n *\n * @method document.executeScript\n * @syntax .execute(body, [args], [callback])\n * @syntax .executeScript(body, [args], [callback])\n * @syntax .document.execute(body, [args], [callback])\n * @syntax .document.executeScript(body, [args], [callback])\n * @param {string|function} body The function body to be injected.\n * @param {Array} args An array of arguments which will be passed to the function.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @returns {*} The script result.\n * @see document.executeAsyncScript\n * @link /#executing-script\n * @api protocol.document\n */\nclass ExecuteScript extends ClientCommand {\n  static get namespacedAliases() {\n    return ['document.execute', 'execute', 'executeScript'];\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    const {script, scriptArgs} = this;\n\n    this.executeScriptHandler('executeScript', script, scriptArgs, callback);\n  }\n\n  command(script, args, callback) {\n    if (!script) {\n      throw new Error('First argument passed to .executeScript() must be defined.');\n    }\n\n    if (arguments.length === 1) {\n      args = [];\n    } else if (arguments.length === 2 && isFunction(arguments[1])) {\n      callback = arguments[2];\n      args = [];\n    }\n\n    this.script = script;\n    this.scriptArgs = args;\n\n    return super.command(callback);\n  }\n};\n\nmodule.exports = ExecuteScript;\n"
  },
  {
    "path": "lib/api/client-commands/document/injectScript.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Utility command to load an external script into the page specified by url.\n *\n * @example\n * module.exports = {\n *   'inject external script': function (browser) {\n *      browser.document.injectScript('<script-url>', function () {\n *        console.log('script injected successfully');\n *      });\n *   },\n *\n *   'inject external script using ES6 async/await': async function (browser) {\n *      await browser.document.injectScript('<script-url>', 'injected-script');\n *   }\n * };\n *\n * @syntax .document.injectScript(scriptUrl, [callback])\n * @syntax .document.injectScript(scriptUrl, id, [callback])\n * @method document.injectScript\n * @param {string} scriptUrl The script file url\n * @param {string} [id] DOM element id to be set on the script tag.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @returns {HTMLScriptElement} The newly created script tag.\n * @api protocol.document\n */\nclass InjectScript extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    const {scriptFn, scriptArgs} = this;\n\n    this.transportActions.executeScript(scriptFn, scriptArgs, callback);\n  }\n\n  command(scriptUrl, id, callback) {\n    const args = [scriptUrl];\n\n    if (arguments.length === 2 && typeof arguments[1] == 'function') {\n      callback = arguments[1];\n    } else if (typeof id == 'string') {\n      args.push(id);\n    }\n\n    // eslint-disable-next-line\n    const script = function(u,i) {return (function(d){var e=d.createElement('script');var m=d.getElementsByTagName('head')[0];e.src=u;if(i){e.id=i;}m.appendChild(e);return e;})(document);};\n\n    this.scriptFn = 'var passedArgs = Array.prototype.slice.call(arguments,0); return (' +\n      script.toString() + ').apply(window, passedArgs);';\n    this.scriptArgs = args;\n\n    return super.command(callback);\n  }\n};\n\nmodule.exports = InjectScript;\n"
  },
  {
    "path": "lib/api/client-commands/document/source.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Get the string serialized source of the current page.\n *\n * @example\n * module.exports = {\n *   'get page source': function (browser) {\n *      browser.document.source(function (result) {\n *        console.log('current page source:', result.value);\n *      });\n *   },\n *\n *   'get page source using ES6 async/await': async function (browser) {\n *      const pageSource = await browser.document.source();\n *      console.log('current page source:', pageSource);\n *   }\n * };\n *\n * @syntax .document.source([callback])\n * @method document.source\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {string} String serialized source of the current page.\n * @link /#get-page-source\n * @api protocol.document\n */\nclass Source extends ClientCommand {\n  static get namespacedAliases() {\n    return 'document.pageSource';\n  }\n\n  performAction(callback) {\n    this.transportActions.getPageSource(callback);\n  }\n}\n\nmodule.exports = Source;\n"
  },
  {
    "path": "lib/api/client-commands/enablePerformanceMetrics.js",
    "content": "const ClientCommand = require('./_base-command.js');\nconst {Logger} = require('../../utils');\n\n/**\n * Enable/disable the collection of performance metrics in the browser. Metrics collection only begin after this command is called.\n *\n * @example\n *  describe('collect performance metrics', function() {\n *    it('enables the metrics collection, does some stuff and collects the metrics', function() {\n *      browser\n *        .enablePerformanceMetrics()\n *        .navigateTo('https://www.google.com')\n *        .getPerformanceMetrics((result) => {\n *          if (result.status === 0) {\n *            const metrics = result.value;\n *            console.log(metrics);\n *          }\n *        });\n *    });\n *  });\n *\n * @method enablePerformanceMetrics\n * @syntax .enablePerformanceMetrics([enable], [callback])\n * @param {boolean} [enable] Whether to enable or disable the performance metrics collection. Default: `true`.\n * @param {function} [callback] callback function to be called when the command finishes.\n * @api protocol.cdp\n * @since 2.2.0\n * @moreinfo web.dev/metrics/\n * @moreinfo pptr.dev/api/puppeteer.page.metrics/\n */\nclass EnablePerformanceMetrics extends ClientCommand {\n\n  performAction(callback) {\n\n    if (!this.api.isChrome() && !this.api.isEdge()) {\n      const error = new Error('The command .enablePerformanceMetrics() is only supported in Chrome and Edge drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    const {enable = true} = this;\n\n    this.transportActions.enablePerformanceMetrics(enable, callback);\n  }\n\n  command(enable, callback) {\n    this.enable = enable;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = EnablePerformanceMetrics;\n"
  },
  {
    "path": "lib/api/client-commands/end.js",
    "content": "const EventEmitter = require('events');\n\n/**\n * Ends the session. Uses session protocol command.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.end();\n * };\n *\n * @method end\n * @syntax .end([callback])\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see session\n * @api protocol.sessions\n */\nclass End extends EventEmitter {\n  command(forceEnd = !this.reuseBrowser, callback) {\n\n    if (arguments.length === 1 && typeof arguments[0] === 'function') {\n      callback = forceEnd;\n      forceEnd = !this.reuseBrowser;\n    }\n\n    const client = this.client;\n\n    if (this.api.sessionId && forceEnd) {\n      this.api.session('delete', result => {\n        client.sessionId = null;\n        client.setApiProperty('sessionId', null);\n\n        this.client.transport.closeDriver('FINISHED').then(() => {\n          this.complete(callback, result);\n        });\n      });\n    } else {\n      setImmediate(() => {\n        this.complete(callback, null);\n      });\n    }\n\n    return this.client.api;\n  }\n\n  complete(callback, response) {\n    let result;\n    if (typeof callback === 'function') {\n      result = callback.call(this.api, response);\n    }\n\n    this.emit('complete', result);\n  }\n}\n\nmodule.exports = End;\n"
  },
  {
    "path": "lib/api/client-commands/getCookie.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Retrieve a single cookie visible to the current page. The cookie is returned as a cookie JSON object, as defined [here](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#cookie-json-object).\n *\n * Uses `cookie` protocol command.\n *\n * @example\n * this.demoTest = function(browser) {\n *   browser.getCookie(name, function callback(result) {\n *     this.assert.equal(result.value, '123456');\n *     this.assert.equal(result.name, 'test_cookie');\n *   });\n * }\n *\n *\n * @method getCookie\n * @param {string} name The cookie name.\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.cookies\n * @syntax .getCookie(name, callback)\n * @see cookie\n * @returns {object|null} The cookie object as a selenium cookie JSON object or null if the cookie wasn't found.\n * @deprecated In favour of `.cookies.get()`.\n */\nclass GetCookie extends ClientCommand {\n  get returnsFullResultObject() {\n    return false;\n  }\n\n  get resolvesWithFullResultObject() {\n    return false;\n  }\n\n  /**\n   * Perform the .cookie() protocol action and pass the result to the supplied callback\n   *  with the original \"this\" context\n   *\n   * @param {function} actionCallback\n   */\n  performAction(actionCallback) {\n    const {cookieName} = this;\n\n    this.api.cookie('GET', function(result) {\n      let value = null;\n\n      if (Array.isArray(result.value) && result.value.length > 0) {\n        for (let i = 0; i < result.value.length; i++) {\n          if (result.value[i].name === cookieName) {\n            value = result.value[i];\n            break;\n          }\n        }\n      }\n\n      actionCallback.call(this, {\n        value\n      });\n    });\n  }\n\n  command(name, callback) {\n    this.cookieName = name;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = GetCookie;\n"
  },
  {
    "path": "lib/api/client-commands/getCookies.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Retrieve all cookies visible to the current page. The cookies are returned as an array of cookie JSON object, as defined [here](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#cookie-json-object).\n *\n * Uses `cookie` protocol command.\n *\n * @example\n * this.demoTest = function(browser) {\n *   browser.getCookies(function callback(result) {\n *     this.assert.equal(result.value.length, 1);\n *     this.assert.equal(result.value[0].name, 'test_cookie');\n *   });\n * }\n *\n *\n * @method getCookies\n * @param {function} callback The callback function which will receive the response as an argument.\n * @syntax .getCookies(callback)\n * @api protocol.cookies\n * @see cookie\n * @returns {Array.<object>} A list of cookies.\n * @deprecated In favour of `.cookies.getAll()`.\n */\n\nclass GetCookies extends ClientCommand {\n  performAction(callback) {\n    this.api.cookie('GET', callback);\n  }\n}\n\nmodule.exports = GetCookies;\n"
  },
  {
    "path": "lib/api/client-commands/getLog.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Gets a log from Selenium.\n *\n * @example\n * this.demoTest = function(client) {\n *   this.getLog('browser', function(logEntriesArray) {\n *     console.log('Log length: ' + logEntriesArray.length);\n *     logEntriesArray.forEach(function(log) {\n *        console.log('[' + log.level + '] ' + log.timestamp + ' : ' + log.message);\n *      });\n *   });\n * };\n *\n *\n * @method getLog\n * @syntax .getLog([typeString], callback)\n * @param {string|function} typeString Log type to request\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.sessions\n * @see getLogTypes\n * @deprecated In favour of `.logs.getSessionLog()`.\n */\nclass GetLog extends ClientCommand {\n  get returnsFullResultObject() {\n    return false;\n  }\n\n  get resolvesWithFullResultObject() {\n    return false;\n  }\n\n  performAction(actionCallback) {\n    this.api.sessionLog(this.typeString, actionCallback);\n  }\n\n  command(typeString = 'browser', callback) {\n    if (arguments.length === 1 && typeof arguments[0] == 'function') {\n      callback = arguments[0];\n      typeString = 'browser';\n    }\n\n    this.typeString = typeString;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = GetLog;\n"
  },
  {
    "path": "lib/api/client-commands/getLogTypes.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Gets the available log types. More info about log types in WebDriver can be found here: https://github.com/SeleniumHQ/selenium/wiki/Logging\n *\n * @example\n * this.demoTest = function(client) {\n *   this.getLogTypes(function(typesArray) {\n *     console.log(typesArray);\n *   });\n * };\n *\n *\n * @method getLogTypes\n * @syntax .getLogTypes(callback)\n * @param {function} callback Callback function which is called with the result value.\n * @returns {Array} Available log types\n * @api protocol.sessions\n * @see sessionLogTypes\n * @deprecated In favour of `.logs.getSessionLogTypes()`.\n */\nclass GetLogTypes extends ClientCommand {\n  get returnsFullResultObject() {\n    return false;\n  }\n\n  get resolvesWithFullResultObject() {\n    return false;\n  }\n\n  performAction(actionCallback) {\n    this.api.sessionLogTypes(actionCallback);\n  }\n\n}\n\nmodule.exports = GetLogTypes;\n"
  },
  {
    "path": "lib/api/client-commands/getPerformanceMetrics.js",
    "content": "const ClientCommand = require('./_base-command.js');\nconst {Logger} = require('../../utils');\n\n/**\n * Get the performance metrics from the browser. Metrics collection only begin after `enablePerformanceMetrics()` command is called.\n *\n * @example\n *  describe('collect performance metrics', function() {\n *    it('enables the metrics collection, does some stuff and collects the metrics', function() {\n *      browser\n *        .enablePerformanceMetrics()\n *        .navigateTo('https://www.google.com')\n *        .getPerformanceMetrics((result) => {\n *          if (result.status === 0) {\n *            const metrics = result.value;\n *            console.log(metrics);\n *          }\n *        });\n *    });\n *  });\n *\n * @method getPerformanceMetrics\n * @syntax .getPerformanceMetrics(callback)\n * @param {function} callback Callback function called with an object containing the performance metrics as argument.\n * @returns {Promise<object>} Metrics collected between the last call to `enablePerformanceMetrics()` command and this command.\n * @api protocol.cdp\n * @since 2.2.0\n * @moreinfo web.dev/metrics/\n * @moreinfo pptr.dev/api/puppeteer.page.metrics/\n */\nclass GetPerformanceMetrics extends ClientCommand {\n\n  performAction(callback) {\n\n    if (!this.api.isChrome()  && !this.api.isEdge()) {\n      const error =  new Error('The command .getPerformanceMetrics() is only supported in Chrome and Edge drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    this.transportActions.getPerformanceMetrics(callback);\n  }\n\n  command(callback) {\n    return super.command(callback);\n  }\n}\n\nmodule.exports = GetPerformanceMetrics;\n"
  },
  {
    "path": "lib/api/client-commands/getTitle.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Returns the title of the current page. Uses title protocol command.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.getTitle(function(title) {\n *      this.assert.equal(typeof title, 'string');\n *      this.assert.equal(title, 'Nightwatch.js');\n *    });\n *  };\n *\n *\n * @method getTitle\n * @syntax .getTitle(callback)\n * @param {function} callback Callback function which is called with the result value.\n * @see title\n * @returns {string} The page title.\n * @api protocol.navigation\n */\nclass GetTitle extends ClientCommand {\n  get returnsFullResultObject() {\n    return false;\n  }\n\n  performAction(callback) {\n    this.api.title(callback);\n  }\n}\n\nmodule.exports = GetTitle;\n"
  },
  {
    "path": "lib/api/client-commands/getWindowPosition.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Retrieves the current window position.\n *\n * For clients which are compatible with the [W3C Webdriver API](https://w3c.github.io/webdriver/), `getWindowPosition` is an alias of `getWindowRect`.\n *\n * The `getWindowRect` command returns both dimensions and position of the window, using the `windowRect` protocol command.\n *\n * @example\n * module.exports = {\n *   'demo test .getWindowPosition()': function(browser) {\n *      // Retrieve the attributes\n *      browser.getWindowPosition(function(value) {\n *        console.log(value);\n *      });\n *   },\n *\n *   'getWindowPosition ES6 demo test': async function(browser) {\n *      const value = await browser.getWindowPosition();\n *      console.log('value', value);\n *   }\n * }\n *\n * @method getWindowPosition\n * @syntax .getWindowPosition([callback])\n * @param {function} callback Callback function to be called when the command finishes.\n * @see windowRect\n * @api protocol.contexts\n * @deprecated In favour of `.window.getPosition()`.\n */\nclass GetWindowPosition extends ClientCommand {\n  get returnsFullResultObject() {\n    return false;\n  }\n\n  get resolvesWithFullResultObject() {\n    return false;\n  }\n\n  performAction(callback) {\n    this.api.windowPosition('current', callback);\n  }\n}\n\nmodule.exports = GetWindowPosition;\n"
  },
  {
    "path": "lib/api/client-commands/getWindowRect.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Change or get the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect). This is defined as a dictionary of the `screenX`, `screenY`, `outerWidth` and `outerHeight` attributes of the window.\n *\n * Its JSON representation is the following:\n * - `x` - window's screenX attribute;\n * - `y` - window's screenY attribute;\n * - `width` - outerWidth attribute;\n * - `height` - outerHeight attribute.\n *\n * All attributes are in in CSS pixels. To change the window react, you can either specify `width` and `height`, `x` and `y` or all properties together.\n *\n * @example\n * module.exports = {\n *   'demo test .getWindowRect()': function(browser) {\n *      // Retrieve the attributes\n *      browser.getWindowRect(function(value) {\n *        console.log(value);\n *      });\n *   },\n *\n *   'getWindowRect ES6 demo test': async function(browser) {\n *      const resultValue = await browser.getWindowRect();\n *      console.log('result value', resultValue);\n *   }\n * }\n *\n * @w3c\n * @method getWindowRect\n * @link /#dfn-get-window-rect\n * @param {function} callback Callback function to be called when the command finishes.\n * @see windowRect\n * @api protocol.contexts\n * @deprecated In favour of `.window.getRect()`.\n */\nclass GetWindowRect extends ClientCommand {\n  get returnsFullResultObject() {\n    return false;\n  }\n\n  get resolvesWithFullResultObject() {\n    return false;\n  }\n\n  performAction(callback) {\n    this.api.windowRect(null, callback);\n  }\n}\n\nmodule.exports = GetWindowRect;\n"
  },
  {
    "path": "lib/api/client-commands/getWindowSize.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Retrieves the current window size.\n *\n * For clients which are compatible with the [W3C Webdriver API](https://w3c.github.io/webdriver/), `getWindowSize` is an alias of `getWindowRect`.\n *\n * The `getWindowRect` command returns both dimensions and position of the window, using the `windowRect` protocol command.\n *\n * @example\n * module.exports = {\n *   'demo test .getWindowSize()': function(browser) {\n *      // Retrieve the attributes\n *      browser.getWindowSize(function(value) {\n *        console.log(value);\n *      });\n *   },\n *\n *   'getWindowSize ES6 demo test': async function(browser) {\n *      const value = await browser.getWindowSize();\n *      console.log('value', value);\n *   }\n * }\n *\n *\n * @method getWindowSize\n * @syntax .getWindowSize([callback])\n * @param {function} callback Callback function to be called when the command finishes.\n * @see windowRect\n * @api protocol.contexts\n * @deprecated In favour of `.window.getSize()`.\n */\nclass GetWindowSize extends ClientCommand {\n  get returnsFullResultObject() {\n    return false;\n  }\n\n  get resolvesWithFullResultObject() {\n    return false;\n  }\n\n  performAction(callback) {\n    this.api.windowSize('current', callback);\n  }\n}\n\nmodule.exports = GetWindowSize;\n"
  },
  {
    "path": "lib/api/client-commands/init.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * This command is an alias to url and also a convenience method when called without any arguments in the sense that it performs a call to .url() with passing the value of `launch_url` field from the settings file.\n * Uses `url` protocol command.\n *\n * @example\n * this.demoTest = function (client) {\n *   client.init();\n * };\n *\n *\n * @method init\n * @param {string} [url] Url to navigate to.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see url\n * @api protocol.navigation\n */\nclass Init extends ClientCommand {\n\n  performAction(callback) {\n    this.api.url(this.url, callback);\n  }\n\n  command(url, callback) {\n    if (arguments.length === 0 || typeof arguments[0] == 'function') {\n      url = this.api.launchUrl;\n    }\n\n    if (arguments.length === 0) {\n      callback = function() {};\n    } else if (typeof arguments[0] == 'function') {\n      callback = arguments[0];\n    }\n\n    if (!url) {\n      // eslint-disable-next-line no-console\n      console.warn('No url defined for .init() command.');\n    }\n\n    this.url = url;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = Init;\n"
  },
  {
    "path": "lib/api/client-commands/injectScript.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Utility command to load an external script into the page specified by url.\n *\n * @example\n * this.demoTest = function(client) {\n *   this.injectScript(\"{script-url}\", function() {\n *     // we're all done here.\n *   });\n * };\n *\n *\n * @method injectScript\n * @param {string} scriptUrl The script file url\n * @param {string} [id] Dom element id to be set on the script tag.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.document\n * @returns {HTMLScriptElement} The newly created script tag.\n * @deprecated In favour of `.document.injectScript()`.\n */\nclass InjectScript extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    // eslint-disable-next-line\n    this.api.execute(function(u,i) {return (function(d){var e=d.createElement('script');var m=d.getElementsByTagName('head')[0];e.src=u;if(i){e.id=i;}m.appendChild(e);return e;})(document);}, this.args, callback);\n  }\n\n  command(scriptUrl, id, callback) {\n    this.args = [scriptUrl];\n    if (arguments.length === 2 && typeof arguments[1] == 'function') {\n      callback = arguments[1];\n    } else if (typeof id == 'string') {\n      this.args.push(id);\n    }\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = InjectScript;\n"
  },
  {
    "path": "lib/api/client-commands/isLogAvailable.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Utility command to test if the log type is available.\n *\n * @example\n * this.demoTest = function(browser) {\n *   browser.isLogAvailable('browser', function(isAvailable) {\n *     // do something more in here\n *   });\n * }\n *\n *\n * @method isLogAvailable\n * @syntax .isLogAvailable([typeString], callback)\n * @param {string|function} typeString Type of log to test\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.sessions\n * @see getLogTypes\n * @deprecated In favour of `.logs.isSessionLogAvailable()`.\n */\nclass IsLogAvailable extends ClientCommand {\n  performAction(actionCallback) {\n    const {typeString} = this;\n\n    this.api.getLogTypes(function(types) {\n      let isAvailable;\n\n      try {\n        isAvailable = Array.isArray(types) && types.indexOf(typeString) >= 0;\n      } catch (err) {\n        isAvailable = false;\n      }\n\n      actionCallback.call(this, isAvailable);\n    });\n  }\n\n  command(typeString = 'browser', callback) {\n    if (arguments.length === 1 && typeof arguments[0] == 'function') {\n      callback = arguments[0];\n      typeString = 'browser';\n    }\n\n    this.typeString = typeString;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = IsLogAvailable;\n"
  },
  {
    "path": "lib/api/client-commands/logs/captureBrowserConsoleLogs.js",
    "content": "const ClientCommand = require('../_base-command.js');\nconst {Logger} = require('../../../utils');\n\n/**\n * Listen to the `console` events (ex. `console.log` event) and register callback to process the same.\n *\n * @example\n *  describe('capture console events', function() {\n *    it('captures and logs console.log event', function() {\n *      browser\n *        .captureBrowserConsoleLogs((event) => {\n *          console.log(event.type, event.timestamp, event.args[0].value);\n *        })\n *        .navigateTo('https://www.google.com')\n *        .executeScript(function() {\n *          console.log('here');\n *        }, []);\n *    });\n *  });\n *\n * @method captureBrowserConsoleLogs\n * @syntax .captureBrowserConsoleLogs(onEventCallback)\n * @param {function} onEventCallback Callback function called whenever a new console event is captured.\n * @api protocol.cdp\n * @since 2.2.0\n * @moreinfo nightwatchjs.org/guide/running-tests/capture-console-messages.html\n */\nclass StartCapturingLogs extends ClientCommand {\n  static get namespacedAliases() {\n    return 'captureBrowserConsoleLogs';\n  }\n\n  performAction(callback) {\n    if (!this.api.isChrome()  && !this.api.isEdge()) {\n      const error = new Error('The command .captureBrowserConsoleLogs() is only supported in Chrome and Edge drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    const userCallback = this.userCallback;\n    if (userCallback === undefined) {\n      const error =  new Error('Callback is missing from .captureBrowserConsoleLogs() command.');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    this.transportActions.startLogsCapture(userCallback, callback);\n  }\n\n  command(userCallback, callback) {\n    this.userCallback = userCallback;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = StartCapturingLogs;\n"
  },
  {
    "path": "lib/api/client-commands/logs/captureBrowserExceptions.js",
    "content": "const ClientCommand = require('../_base-command.js');\nconst {Logger} = require('../../../utils');\n\n/**\n * Catch the JavaScript exceptions thrown in the browser.\n *\n * @example\n *  describe('catch browser exceptions', function() {\n *    it('captures the js exceptions thrown in the browser', async function() {\n *      await browser.captureBrowserExceptions((event) => {\n *        console.log('>>> Exception:', event);\n *      });\n *\n *      await browser.navigateTo('https://duckduckgo.com/');\n *\n *      const searchBoxElement = await browser.findElement('input[name=q]');\n *      await browser.executeScript(function(_searchBoxElement) {\n *        _searchBoxElement.setAttribute('onclick', 'throw new Error(\"Hello world!\")');\n *      }, [searchBoxElement]);\n *\n *      await browser.elementIdClick(searchBoxElement.getId());\n *    });\n *  });\n *\n * @method captureBrowserExceptions\n * @syntax .captureBrowserExceptions(onExceptionCallback)\n * @param {function} onExceptionCallback Callback function called whenever a new exception is thrown in the browser.\n * @api protocol.cdp\n * @since 2.2.0\n * @moreinfo nightwatchjs.org/guide/running-tests/catch-js-exceptions.html\n */\nclass CatchJsExceptions extends ClientCommand {\n  static get namespacedAliases() {\n    return 'captureBrowserExceptions';\n  }\n\n  performAction(callback) {\n    if (!this.api.isChrome() && !this.api.isEdge()) {\n      const error = new Error('The command .captureBrowserExceptions() is only supported in Chrome and Edge drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    const userCallback = this.userCallback;\n    if (userCallback === undefined) {\n      const error = new Error('Callback is missing from .captureBrowserExceptions() command.');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    this.transportActions.catchJsExceptions(userCallback, callback);\n  }\n\n  command(userCallback, callback) {\n    this.userCallback = userCallback;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = CatchJsExceptions;\n"
  },
  {
    "path": "lib/api/client-commands/logs/getSessionLog.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Gets a log from Selenium.\n *\n * @example\n * describe('get log from Selenium', function() {\n *   it('get browser log (default)', function(browser) {\n *     browser.logs.getSessionLog(function(result) {\n *       const logEntriesArray = result.value;\n *       console.log('Log length: ' + logEntriesArray.length);\n *       logEntriesArray.forEach(function(log) {\n *         console.log('[' + log.level + '] ' + log.timestamp + ' : ' + log.message);\n *       });\n *     });\n *   });\n *\n *   it('get driver log with ES6 async/await', async function(browser) {\n *     const driverLogAvailable = await browser.logs.isSessionLogAvailable('driver');\n *     if (driverLogAvailable) {\n *       const logEntriesArray = await browser.logs.getSessionLog('driver');\n *       logEntriesArray.forEach(function(log) {\n *         console.log('[' + log.level + '] ' + log.timestamp + ' : ' + log.message);\n *       });\n *     }\n *   });\n * });\n *\n * @syntax .logs.getSessionLog([typeString], [callback])\n * @method logs.getSessionLog\n * @param {string} typeString Log type to request. Default: 'browser'. Use `.logs.getLogTypes()` command to get all available log types.\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {Array<object>} An array of log Entry objects with properties as defined [here](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/lib/logging_exports_Entry.html) (see Instance Properties).\n * @see logs.getSessionLogTypes\n * @api protocol.sessions\n */\nclass GetSessionLog extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.getLogContents(this.typeString, callback);\n  }\n\n  command(typeString = 'browser', callback) {\n    if (arguments.length === 1 && typeof arguments[0] == 'function') {\n      callback = arguments[0];\n      typeString = 'browser';\n    }\n\n    this.typeString = typeString;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = GetSessionLog;\n"
  },
  {
    "path": "lib/api/client-commands/logs/getSessionLogTypes.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Gets the available log types. More info about log types in WebDriver can be found here: https://github.com/SeleniumHQ/selenium/wiki/Logging\n *\n * @example\n * describe('get available log types', function() {\n *   it('get log types', function(browser) {\n *     browser.logs.getSessionLogTypes(function(result) {\n *       const logTypes = result.value;\n *       console.log('Log types available:', logTypes);\n *     });\n *   });\n *\n *   it('get log types with ES6 async/await', async function(browser) {\n *     const logTypes = await browser.logs.getSessionLogTypes();\n *     console.log('Log types available:', logTypes);\n *   });\n * });\n *\n * @syntax .logs.getSessionLogTypes([callback])\n * @method logs.getSessionLogTypes\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {Array<string>} Available log types.\n * @see logs.getSessionLog\n * @api protocol.sessions\n */\nclass GetSessionLogTypes extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.getSessionLogTypes(callback);\n  }\n}\n\nmodule.exports = GetSessionLogTypes;\n"
  },
  {
    "path": "lib/api/client-commands/logs/isSessionLogAvailable.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Utility command to test if the log type is available.\n *\n * @example\n * describe('test if the log type is available', function() {\n *   it('test browser log type', function(browser) {\n *     browser.logs.isSessionLogAvailable('browser', function(result) {\n *       const isAvailable = result.value;\n *       if (isAvailable) {\n *         // do something more in here\n *       }\n *     });\n *   });\n *\n *   it('test driver log type with ES6 async/await', async function(browser) {\n *     const isAvailable = await browser.logs.isSessionLogAvailable('driver');\n *     if (isAvailable) {\n *       // do something more in here\n *     }\n *   });\n * });\n *\n * @syntax .logs.isSessionLogAvailable([typeString], [callback])\n * @method logs.isSessionLogAvailable\n * @param {string} typeString Type of log to test. Default: 'browser'.\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {boolean} True if log type is available.\n * @see logs.getSessionLogTypes\n * @api protocol.sessions\n */\nclass IsSessionLogAvailable extends ClientCommand {\n  performAction(callback) {\n    const {typeString} = this;\n\n    this.transportActions.getSessionLogTypes(function(result) {\n      if (result.status === 0) {\n        const types = result.value;\n        let isAvailable;\n\n        try {\n          isAvailable = Array.isArray(types) && types.indexOf(typeString) >= 0;\n        } catch (err) {\n          isAvailable = false;\n        }\n\n        result.value = isAvailable;\n      }\n\n      callback.call(this, result);\n    });\n  }\n\n  command(typeString = 'browser', callback) {\n    if (arguments.length === 1 && typeof arguments[0] == 'function') {\n      callback = arguments[0];\n      typeString = 'browser';\n    }\n\n    this.typeString = typeString;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = IsSessionLogAvailable;\n"
  },
  {
    "path": "lib/api/client-commands/maximizeWindow.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Maximizes the current window.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.maximizeWindow();\n *  };\n *\n *\n * @method maximizeWindow\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see windowMaximize\n * @api protocol.contexts\n * @deprecated In favour of `.window.maximize()`.\n */\nclass WindowMaximize extends ClientCommand {\n\n  performAction(callback) {\n    this.api.windowMaximize('current', callback);\n  }\n}\n\nmodule.exports = WindowMaximize;\n"
  },
  {
    "path": "lib/api/client-commands/network/captureRequests.js",
    "content": "const ClientCommand = require('../_base-command.js');\nconst {Logger} = require('../../../utils');\n\n/**\n * Capture outgoing network calls from the browser.\n *\n * @example\n *  describe('capture network requests', function() {\n *    it('captures and logs network requests as they occur', function(this: ExtendDescribeThis<{requestCount: number}>) {\n *      this.requestCount = 1;\n *      browser\n *        .network.captureRequests((requestParams) => {\n *          console.log('Request Number:', this.requestCount!++);\n *          console.log('Request URL:', requestParams.request.url);\n *          console.log('Request method:', requestParams.request.method);\n *          console.log('Request headers:', requestParams.request.headers);\n *        })\n *        .navigateTo('https://www.google.com');\n *    });\n *  });\n *\n * @method network.captureRequests\n * @syntax .captureNetworkRequests(onRequestCallback)\n * @syntax .network.captureRequests(onRequestCallback)\n * @param {function} onRequestCallback Callback function called whenever a new outgoing network request is made.\n * @api protocol.cdp\n * @since 2.2.0\n * @moreinfo nightwatchjs.org/guide/network-requests/capture-network-calls.html\n */\nclass CaptureNetworkCalls extends ClientCommand {\n\n  static get namespacedAliases() {\n    return 'captureNetworkRequests';\n  }\n\n  performAction(callback) {\n\n    if (!this.api.isChrome() && !this.api.isEdge()) {\n      const error = new Error('The command .captureNetworkRequests() is only supported in Chrome and Edge drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    const userCallback = this.userCallback;\n    if (userCallback === undefined) {\n      const error =  new Error('Callback is missing from .captureNetworkRequests() command.');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    this.transportActions.interceptNetworkCalls(userCallback, callback);\n  }\n\n  command(userCallback, callback) {\n    this.userCallback = userCallback;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = CaptureNetworkCalls;\n"
  },
  {
    "path": "lib/api/client-commands/network/mockResponse.js",
    "content": "const ClientCommand = require('../_base-command.js');\nconst {Logger} = require('../../../utils');\n\n/**\n * Intercept the request made on a particular URL and mock the response.\n *\n * @example\n *  describe('mock network response', function() {\n *    it('intercepts the request made to Google search and mocks its response', function() {\n *      browser\n *        .network.mockResponse('https://www.google.com/', {\n *          status: 200,\n *          headers: {\n *            'Content-Type': 'UTF-8'\n *          },\n *          body: 'Hello there!'\n *        })\n *        .navigateTo('https://www.google.com/')\n *        .pause(2000);\n *    });\n *  });\n *\n * @method network.mockResponse\n * @syntax .mockNetworkResponse(urlToIntercept, {status, headers, body}, [callback])\n * @syntax .network.mockResponse(urlToIntercept, {status, headers, body}, [callback])\n * @param {string} urlToIntercept URL to intercept and mock the response from.\n * @param {object} response Response to return. Defaults: `{status: 200, headers: {}, body: ''}`.\n * @param {function} [callback] Callback function to be called when the command finishes.\n * @api protocol.cdp\n * @since 2.2.0\n * @moreinfo nightwatchjs.org/guide/network-requests/mock-network-response.html\n */\nclass MockNetworkResponse extends ClientCommand {\n\n  static get namespacedAliases() {\n    return 'mockNetworkResponse';\n  }\n\n  performAction(callback) {\n\n    if (!this.api.isChrome()  && !this.api.isEdge()) {\n      const error =  new Error('The command .mockNetworkResponse() is only supported in Chrome and Edge drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    const {response = {}} = this;\n    let {urlToIntercept = ''} = this;\n\n    if (urlToIntercept.startsWith('/')) {\n      const launchUrl = this.api.launchUrl || this.api.globals.launchUrl || '';\n      const needsSlash = launchUrl.endsWith('/');\n      const slashDel = needsSlash ? '/' : '';\n      urlToIntercept = `${launchUrl}${slashDel}${urlToIntercept}`;\n    }\n\n    this.transportActions.mockNetworkResponse(urlToIntercept, response, callback);\n  }\n\n  command(urlToIntercept, response, callback) {\n    this.urlToIntercept = urlToIntercept;\n    this.response = response;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = MockNetworkResponse;\n"
  },
  {
    "path": "lib/api/client-commands/network/setConditions.js",
    "content": "const ClientCommand = require('../_base-command.js');\nconst {Logger} = require('../../../utils');\n\n/**\n *\n * Command to set Chrome network emulation settings.\n *\n * @example\n * describe('set network conditions', function() {\n *  it('sets the network conditions',function() {\n *    browser\n *     .network.setConditions({\n *      offline: false,\n *      latency: 3000,\n *      download_throughput: 500 * 1024,\n *      upload_throughput: 500 * 1024\n *    });\n *  });\n * });\n *\n * @method network.setConditions\n * @syntax .setNetworkConditions(spec, [callback])\n * @syntax .network.setConditions(spec, [callback])\n * @param {object} spec\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.sessions\n */\nclass SetNetworkConditions extends ClientCommand {\n\n  static get namespacedAliases() {\n    return 'setNetworkConditions';\n  }\n\n  performAction(callback) {\n    if (!this.api.isChrome() && !this.api.isEdge()) {\n      const error = new Error('The command .setNetworkConditions() is only supported in Chromium based drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    const {spec} = this;\n\n    this.transportActions.setNetworkConditions(spec, callback);\n  }\n\n  command(spec, callback) {\n    this.spec = spec;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetNetworkConditions;\n"
  },
  {
    "path": "lib/api/client-commands/pageSource.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Returns the page source.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.pageSource(function(pageSource) {\n *      console.log(pageSource);\n *    });\n *  };\n *\n *\n * @method pageSource\n * @syntax .pageSource(callback)\n * @param {function} callback Callback function which is called with the result value.\n * @see pageSource\n * @returns {string} The page source.\n * @api protocol.pageSource\n * @deprecated In favour of `.document.pageSource()`.\n */\n\nclass PageSource extends ClientCommand {\n  get returnsFullResultObject() {\n    return true;\n  }\n\n  performAction(callback) {\n    this.api.source(callback);\n  }\n}\n\nmodule.exports = PageSource;\n"
  },
  {
    "path": "lib/api/client-commands/pause.js",
    "content": "const EventEmitter = require('events');\nconst readline = require('readline');\nconst Debuggability = require('../../utils/debuggability.js');\n\n/**\n * pause() command provides the following functionalities:\n * - Pause the test execution for the given time in milliseconds.\n * - Pause the test execution indefinitely, until resumed by pressing a key in terminal.\n * - Pause the test execution, and then step over to the next test command (execute the next test command) and pause again.\n *\n * This command will allow you to pause the test execution in between, hop on to the browser to check the state of your\n * application (or use DevTools to debug), and once satisfied, either resume the test execution from where it was left\n * off or step over to the next test command (execute the next test command) and pause again.\n *\n * Stepping over to the next test command would allow you to see what exactly changed in your application when the next\n * test command was executed. You can also use DevTools to monitor those changes, like the network calls that were made\n * during the execution of that command, etc.\n *\n * @example\n * this.demoTest = function (browser) {\n *   // pause for 1000 ms\n *   browser.pause(1000);\n *   // pause indefinitely until resumed\n *   browser.pause();\n * };\n *\n * @method pause\n * @param {number} [ms] The number of milliseconds to wait.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.utilities\n */\nclass Pause extends EventEmitter {\n\n  command(ms, callback) {\n    // If we don't pass the milliseconds, the client will\n    // be suspended indefinitely, until the user presses some\n    // key in the terminal to resume it.\n    if (ms === undefined) {\n      // eslint-disable-next-line\n      console.log(`Paused...\n    Press <space> or F10 to step over to the next test command and pause again.\n    Press d to enter the DEBUG mode.\n    Press Ctrl+C to exit.\n    Press any other key to RESUME.`);\n\n      readline.emitKeypressEvents(process.stdin);\n      process.stdin.resume();\n      if (process.stdin.isTTY) {\n        process.stdin.setRawMode(true);\n      }\n      process.stdin.once('keypress', (str, key) => {\n        if (key.ctrl && key.name === 'c') {\n          this.api.end(function() {\n            process.exit(0);\n          });\n        } else if (key.name === 'space' || key.name === 'f10') {\n          Debuggability.stepOverAndPause = true;\n        } else if (key.name === 'd') {\n          this.api.debug();\n        }\n\n        if (process.stdin.isTTY) {\n          process.stdin.setRawMode(false);\n        }\n        process.stdin.pause();\n\n        // Remove the logged paused... information above\n        readline.moveCursor(process.stdout, 0, -5);\n        readline.clearScreenDown(process.stdout);\n\n        if (callback) {\n          callback.call(this.client.api);\n        }\n\n        this.emit('complete');\n      });\n    } else {\n      setTimeout(() => {\n        // if we have a callback, call it right before the complete event\n        if (callback) {\n          callback.call(this.client.api);\n        }\n\n        this.emit('complete');\n      }, ms);\n    }\n\n    return this;\n  }\n}\n\nmodule.exports = Pause;\n"
  },
  {
    "path": "lib/api/client-commands/perform.js",
    "content": "/**\n * A simple perform command which allows access to the Nightwatch API in a callback. Can be useful if you want to read variables set by other commands.\n *\n * The callback signature can have up to two parameters.\n *  - no parameters: callback runs and perform completes immediately at the end of the execution of the callback.\n *  - one parameter: allows for asynchronous execution within the callback providing a done callback function for completion as the first argument.\n *  - two parameters: allows for asynchronous execution with the Nightwatch `api` object passed in as the first argument, followed by the done callback.\n *\n * In the case of asynchronous execution, the timeout can be controlled by setting the `asyncHookTimeout` global. See [Using test globals](https://nightwatchjs.org/gettingstarted/concepts/#using-test-globals) for more info.\n *\n * @example\n * describe('perform example', function() {\n *   var elementValue;\n *\n *   it('basic perform', function(browser) {\n *     browser\n *       .getValue('.some-element', function(result) {\n *         elementValue = result.value;\n *       })\n *       // other stuff going on ...\n *\n *       // self-completing callback\n *       .perform(function() {\n *         console.log('elementValue', elementValue);\n *         // without any defined parameters, perform\n *         // completes immediately (synchronously)\n *       })\n *\n *       // returning a Promise\n *       .perform(async function() {\n *         console.log('elementValue', elementValue);\n *         // potentially other async stuff going on\n *\n *         return elementValue;\n *       })\n *\n *       // DEPRECATED: asynchronous completion including api (client)\n *       .perform(function(client, done) {\n *         console.log('elementValue', elementValue);\n *         done();\n *     });\n *   });\n *\n *   it('perform with async', function(browser) {\n *     const result = await browser.perform(async function() {\n *       return 100;\n *     });\n *     console.log('result:', result); // 100\n *   })\n * }\n *\n *\n * @method perform\n * @param {function} callback The function to run as part of the queue.\n * @api protocol.utilities\n */\nconst {Actions} = require('selenium-webdriver/lib/input');\nconst EventEmitter = require('events');\n\nclass Perform extends EventEmitter {\n  static get alwaysAsync() {\n    return true;\n  }\n\n  static get avoidPrematureParentNodeResolution() {\n    return true;\n  }\n\n  command(callback = function() {}) {\n    let doneCallback;\n    const asyncHookTimeout = this.client.settings.globals.asyncHookTimeout;\n\n    this.timeoutId = setTimeout(() => {\n      this.emit('error', new Error(`Timeout while waiting (${asyncHookTimeout}ms) for the .perform() command callback to be called.`));\n    }, asyncHookTimeout);\n\n    if (callback.length === 0) {\n      let cbResult = this.runCallback(callback, [this.api]);\n\n      // support for Selenium Actions API:\n      // https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/lib/input_exports_Actions.html\n      if (cbResult instanceof Actions) {\n        cbResult = cbResult.perform();\n      }\n\n      if (cbResult instanceof Promise) {\n        clearTimeout(this.timeoutId);\n        cbResult.then(async result => {\n          if (result instanceof Actions) {\n            result = await result.perform();\n          }\n          this.emit('complete', result);\n        }).catch(err => {\n          this.emit('error', err);\n        });\n\n        return this;\n      }\n\n      doneCallback = () => {\n        clearTimeout(this.timeoutId);\n        this.emit('complete', cbResult);\n      };\n    } else {\n      doneCallback = () => {\n        const args = [(result) => {\n          clearTimeout(this.timeoutId);\n          this.emit('complete', result);\n        }];\n\n        if (callback.length > 1) {\n          args.unshift(this.api);\n        }\n\n        this.runCallback(callback, args);\n      };\n    }\n\n    process.nextTick(doneCallback);\n\n    return this;\n  }\n\n  runCallback(cb, args) {\n    try {\n      return cb.apply(this.api, args);\n    } catch (err) {\n      if (this.timeoutId) {\n        clearTimeout(this.timeoutId);\n      }\n\n      this.emit('error', err);\n    }\n  }\n}\n\nmodule.exports = Perform;\n"
  },
  {
    "path": "lib/api/client-commands/registerBasicAuth.js",
    "content": "const ClientCommand = require('./_base-command.js');\nconst {Logger} = require('../../utils');\n\n/**\n * Automate the input of basic auth credentials whenever they arise.\n * This feature is currently implemented on top of Selenium 4’s CDP(Chrome DevTools Protocol) support, and so only works on those browser that support that protocol\n *\n * @example\n * module.exports = {\n *   'input basic auth credentials': function (browser) {\n *     browser\n *       .registerBasicAuth('admin', 'admin')\n *       .navigateTo('https://the-internet.herokuapp.com/basic_auth');\n *   }\n * };\n *\n * @syntax .registerBasicAuth(username, password, [callback])\n * @method registerBasicAuth\n * @param {string} username\n * @param {string} password\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.userprompts\n */\nclass RegisterBasicAuth extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    if (!this.api.isChrome()  && !this.api.isEdge()) {\n      const error =  new Error('The command .registerBasicAuth() is only supported in Chromium based drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    const {username, password} = this;\n\n    this.transportActions\n      .registerAuth(username, password, callback)\n      .catch(err => {\n        return err;\n      })\n      .then(result => callback(result));\n  }\n\n  command(username, password, callback) {\n    this.username = username;\n    this.password = password;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = RegisterBasicAuth;\n"
  },
  {
    "path": "lib/api/client-commands/resizeWindow.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Resizes the current window.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.resizeWindow(1000, 800);\n *  };\n *\n *\n * @method resizeWindow\n * @param {number} width The new window width.\n * @param {number} height The new window height.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see windowSize\n * @api protocol.contexts\n * @deprecated In favour of `.window.resize()`.\n */\nclass ResizeWindow extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    const {width, height} = this;\n\n    this.transportActions.setWindowSize(\n      width,\n      height\n    ).catch(err => {\n      return err;\n    }).then(result => callback(result));\n\n  }\n\n  command(width, height, callback) {\n    this.width = width;\n    this.height = height;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = ResizeWindow;\n"
  },
  {
    "path": "lib/api/client-commands/saveScreenshot.js",
    "content": "const ClientCommand = require('./_base-command.js');\nconst {Logger, writeToFile} = require('../../utils');\nconst {COMMON_EVENTS: {ScreenshotCreated}, NightwatchEventHub} = require('../../runner/eventHub.js');\n\n/**\n * Take a screenshot of the current page and saves it as the given filename.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.saveScreenshot('/path/to/fileName.png');\n *  };\n *\n *\n * @method saveScreenshot\n * @param {string} fileName The complete path to the file name where the screenshot should be saved.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see screenshot\n * @api protocol.screens\n */\nclass SaveScreenshot extends ClientCommand {\n  performAction(callback) {\n    const {fileName, client} = this;\n\n    this.api.screenshot(this.api.options.log_screenshot_data, function(result) {\n      if (client.transport.isResultSuccess(result) && result.value) {\n        writeToFile(fileName, result.value, 'base64').then(() => {\n          callback.call(this, result);\n\n          NightwatchEventHub.emit(ScreenshotCreated, {\n            path: fileName\n          });\n        }).catch(err => {\n          Logger.error(`Couldn't save screenshot to \"${fileName}\":`);\n          Logger.error(err);\n          callback.call(this, result);\n        });\n      } else {\n        Logger.error(`Couldn't save screenshot to \"${fileName}\":`);\n        callback.call(this, result);\n      }\n    });\n  }\n\n  command(fileName, callback) {\n    this.fileName = fileName;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SaveScreenshot;\n"
  },
  {
    "path": "lib/api/client-commands/saveSnapshot.js",
    "content": "const {URL} = require('url');\nconst {JSDOM} = require('jsdom');\nconst ClientCommand = require('./_base-command.js');\nconst {writeToFile, Logger} = require('../../utils');\n\n/**\n * Take a DOM Snapshot of the current page and saves it as the given filename.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.saveSnapshot('/path/to/fileName.html');\n *  };\n *\n *\n * @method saveSnapshot\n * @param {string} fileName The complete path to the file name where the screenshot should be saved.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n */\nclass SaveSnapshot extends ClientCommand {\n  performAction(callback) {\n    const {fileName, client} = this;\n\n    Promise.all([\n      this.transportActions.getCurrentUrl(),\n      this.transportActions.getPageSource()\n    ])\n      .then(results => {\n        let baseUrl;\n        let pageSource;\n        if (client.transport.isResultSuccess(results[0]) && results[0].value) {\n          baseUrl = new URL(results[0].value).origin;\n        } else {\n          throw new Error('failed to execute getCurrentUrl');\n        }\n\n        if (client.transport.isResultSuccess(results[1]) && results[1].value) {\n          pageSource = results[1].value;\n        } else {\n          throw new Error('failed to fetch pageSource');\n        }\n\n        return this.createSnapshot(baseUrl, pageSource).then(result => {\n          return {data: result, baseUrl};\n        });\n      }).then(result => {\n        const {data, baseUrl} = result;\n\n        return writeToFile(fileName, data).then((fileName => {\n          return {\n            snapshotFilePath: fileName,\n            snapshotUrl: baseUrl\n          };\n        }));\n      }).then(result => {\n        callback.call(this, result);\n      }).catch(err => {\n        Logger.warn(`Couldn't save snapshot to \"${fileName}: ${err.message}`);\n        callback.call(this, err);\n      });\n  }\n\n  async createSnapshot(baseUrl, pageSource) {\n    const dom = new JSDOM(pageSource);\n    const document = dom.window.document;\n\n    // Remove all script tags\n    const scriptTags = document.querySelectorAll('script');\n    scriptTags.forEach(element => {\n      element.remove();\n    });\n\n    const headTag = document.querySelector('head');\n    const baseTag = document.createElement('base');\n    baseTag.setAttribute('href', baseUrl);\n    headTag.prepend(baseTag);\n\n    return dom.serialize();\n  }\n\n  command(fileName, callback) {\n    this.fileName = fileName;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SaveSnapshot;\n"
  },
  {
    "path": "lib/api/client-commands/setCookie.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Set a cookie, specified as a cookie JSON object, as defined [here](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#cookie-json-object).\n *\n * Uses `cookie` protocol command.\n *\n * @example\n * this.demoTest = function(browser) {\n *   browser.setCookie({\n *     name     : \"test_cookie\",\n *     value    : \"test_value\",\n *     path     : \"/\", (Optional)\n *     domain   : \"example.org\", (Optional)\n *     secure   : false, (Optional)\n *     httpOnly : false, // (Optional)\n *     expiry   : 1395002765 // (Optional) time in seconds since midnight, January 1, 1970 UTC\n *   });\n * }\n *\n *\n * @method setCookie\n * @param {object} cookie The cookie object.\n * @syntax .setCookie(cookie, [callback])\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.cookies\n * @see cookie\n * @deprecated In favour of `.cookies.set()`.\n */\nclass SetCookie extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    this.api.cookie('POST', this.cookie, callback);\n  }\n\n  command(cookie, callback) {\n    this.cookie = cookie;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetCookie;\n"
  },
  {
    "path": "lib/api/client-commands/setDeviceDimensions.js",
    "content": "const ClientCommand = require('./_base-command.js');\nconst {Logger} = require('../../utils');\n\n/**\n * Override device mode/dimensions. Call without any arguments to reset the device dimensions back to original.\n *\n * @example\n *  describe('modify device dimensions', function() {\n *    it('modifies the device dimensions and then resets it', function() {\n *      browser\n *        .setDeviceDimensions({\n *          width: 400,\n *          height: 600,\n *          deviceScaleFactor: 50,\n *          mobile: true\n *        })\n *        .navigateTo('https://www.google.com')\n *        .pause(1000)\n *        .setDeviceDimensions()  // resets the device dimensions\n *        .navigateTo('https://www.google.com')\n *        .pause(1000);\n *    });\n *  });\n *\n * @method setDeviceDimensions\n * @syntax .setDeviceDimensions({width, height, deviceScaleFactor, mobile}, [callback])\n * @param {object} [metrics] Device metrics to set. Metric defaults to original if not set.\n * @param {function} [callback] Callback function to be called when the command finishes.\n * @api protocol.cdp\n * @since 2.2.0\n * @moreinfo nightwatchjs.org/guide/mobile-web-testing/override-device-dimensions.html\n */\nclass SetDeviceDimensions extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n\n    if (!this.api.isChrome()  && !this.api.isEdge()) {\n      const error =  new Error('The command .setDeviceDimensions() is only supported in Chrome and Edge drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    // The default values below disables the override for that property (if a user\n    // has not set a property, they'd want that property to not be overridden).\n    const {width = 0, height = 0, deviceScaleFactor = 0, mobile = false} = this.metrics;\n    const metrics = {width, height, deviceScaleFactor, mobile};\n\n    this.transportActions.setDeviceMetrics(metrics, callback);\n  }\n\n  command(metrics, callback) {\n    this.metrics = metrics || {};\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetDeviceDimensions;\n"
  },
  {
    "path": "lib/api/client-commands/setGeolocation.js",
    "content": "const ClientCommand = require('./_base-command.js');\nconst {Logger} = require('../../utils');\n\n/**\n * Mock the geolocation of the browser. Call without any arguments to reset the geolocation back to original.\n *\n * @example\n *  describe('mock geolocation', function() {\n *    it('sets the geolocation to Tokyo, Japan and then resets it', () => {\n *      browser\n *        .setGeolocation({\n *          latitude: 35.689487,\n *          longitude: 139.691706,\n *          accuracy: 100\n *        })  // sets the geolocation to Tokyo, Japan\n *        .navigateTo('https://www.gps-coordinates.net/my-location')\n *        .pause(3000)\n *        .setGeolocation()  // resets the geolocation\n *        .navigateTo('https://www.gps-coordinates.net/my-location')\n *        .pause(3000);\n *    });\n *  });\n *\n * @method setGeolocation\n * @syntax .setGeolocation({latitude, longitude, accuracy}, [callback])\n * @param {object} [coordinates] Latitude, longitude, and accuracy.\n * @param {function} [callback] Callback function to be called when the command finishes.\n * @api protocol.cdp\n * @since 2.2.0\n * @moreinfo nightwatchjs.org/guide/network-requests/mock-geolocation.html\n */\nclass SetGeolocation extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  performAction(callback) {\n    if (!this.api.isChrome()  && !this.api.isEdge()) {\n      const error =  new Error('The command .setGeolocation() is only supported in Chrome and Edge drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    const {latitude, longitude, accuracy} = this.coordinates;\n\n    if (latitude !== undefined && longitude !== undefined) {\n      // Both latitude and longitude are provided\n\n      const coordinates = {latitude, longitude, accuracy};\n      // Set accuracy as 100 if not provided.\n      if (accuracy === undefined) {coordinates.accuracy = 100}\n\n      this.transportActions.setGeolocation(coordinates, callback);\n\n      return;\n    }\n\n    if (latitude === undefined && longitude === undefined) {\n      // Clear geolocation override.\n      this.transportActions.clearGeolocation(callback);\n\n      return;\n    }\n\n    // Exactly one of them is undefined, throw error.\n    const error =  new Error('Please provide both latitude and longitude while using setGeolocation.');\n    Logger.error(error);\n\n    return callback(error);\n  }\n\n  command(coordinates, callback) {\n    this.coordinates = coordinates || {};\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetGeolocation;\n"
  },
  {
    "path": "lib/api/client-commands/setWindowPosition.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Sets the current window position.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.setWindowPosition(0, 0);\n *  };\n *\n *\n * @method setWindowPosition\n * @param {number} offsetX The new window offset x-position.\n * @param {number} offsetY The new window offset y-position.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see windowPosition\n * @api protocol.contexts\n * @deprecated In favour of `.window.setPosition()`.\n */\nclass SetWindowPosition extends ClientCommand {\n  performAction(callback) {\n    this.api.windowPosition('current', this.offsetX, this.offsetY, callback);\n  }\n\n  command(offsetX, offsetY, callback) {\n    this.offsetX = offsetX;\n    this.offsetY = offsetY;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetWindowPosition;\n"
  },
  {
    "path": "lib/api/client-commands/setWindowRect.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Change the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect). This is defined as a dictionary of the `screenX`, `screenY`, `outerWidth` and `outerHeight` attributes of the window.\n *\n * Its JSON representation is the following:\n * - `x` - window's screenX attribute;\n * - `y` - window's screenY attribute;\n * - `width` - outerWidth attribute;\n * - `height` - outerHeight attribute.\n *\n * All attributes are in in CSS pixels. To change the window react, you can either specify `width` and `height`, `x` and `y` or all properties together.\n *\n * @example\n * module.exports = {\n *   'demo test .setWindowRect()': function(browser) {\n *\n *      // Change the screenX and screenY attributes of the window rect.\n *      browser.setWindowRect({x: 500, y: 500});\n *\n *      // Change the width and height attributes of the window rect.\n *      browser.setWindowRect({width: 600, height: 300});\n *\n *      // Retrieve the attributes\n *      browser.setWindowRect(function(result) {\n *        console.log(result.value);\n *      });\n *   },\n *\n *   'setWindowRect ES6 demo test': async function(browser) {\n *      await browser.setWindowRect({\n *        width: 600,\n *        height: 300,\n *        x: 100,\n *        y: 100\n *      });\n *   }\n * }\n *\n * @w3c\n * @link /#dfn-get-window-rect\n * @method setWindowRect\n * @syntax .setWindowRect({width, height, x, y}, [callback]);\n * @param {object} options An object specifying either `width` and `height`, `x` and `y`, or all together to set properties for the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect).\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see windowRect\n * @api protocol.contexts\n * @deprecated In favour of `.window.setRect()`.\n */\nclass SetWindowRect extends ClientCommand {\n  performAction(callback) {\n    this.api.windowRect(this.options, callback);\n  }\n\n  command(options, callback) {\n    this.options = options;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetWindowRect;\n"
  },
  {
    "path": "lib/api/client-commands/setWindowSize.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Sets the current window size in CSS pixels.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.setWindowSize(400, 600);\n *  };\n *\n *\n * @method setWindowSize\n * @param {number} width The new window width in CSS pixels\n * @param {number} height The new window height in CSS pixels\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see windowSize\n * @api protocol.contexts\n * @deprecated In favour of `.window.setSize()`.\n */\nclass SetWindowSize extends ClientCommand {\n  performAction(callback) {\n    this.api.windowSize('current', this.width, this.height, callback);\n  }\n\n  command(width, height, callback) {\n    this.width = width;\n    this.height = height;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetWindowSize;\n"
  },
  {
    "path": "lib/api/client-commands/takeHeapSnapshot.js",
    "content": "const ClientCommand = require('./_base-command.js');\nconst {Logger} = require('../../utils');\n\n/**\n * Take heap snapshot and save it as a `.heapsnapshot` file.\n * The saved snapshot file can then be loaded into Chrome DevTools' Memory tab for inspection.\n *\n * The contents of the heap snapshot are also available in the `value` property of the `result`\n * argument passed to the callback, in string-serialized JSON format.\n *\n * @example\n *  describe('take heap snapshot', function() {\n *    it('takes heap snapshot and saves it as snap.heapsnapshot file', function() {\n *      browser\n *        .navigateTo('https://www.google.com')\n *        .takeHeapSnapshot('./snap.heapsnapshot');\n *    });\n *  });\n *\n * @method takeHeapSnapshot\n * @syntax .takeHeapSnapshot([heapSnapshotLocation], [callback])\n * @param {string} [heapSnapshotLocation] Location where the generated heap snapshot file should be saved.\n * @param {function} [callback] Callback function called with string-serialized heap snapshot as argument.\n * @returns {Promise<string>} Heap snapshot in string-serialized JSON format.\n * @api protocol.cdp\n * @since 2.2.0\n * @moreinfo nightwatchjs.org/guide/running-tests/take-heap-snapshot.html\n */\nclass TakeHeapSnapshot extends ClientCommand {\n\n  performAction(callback) {\n\n    if (!this.api.isChrome()  && !this.api.isEdge()) {\n      const error =  new Error('The command .takeHeapSnapshot() is only supported in Chrome and Edge drivers');\n      Logger.error(error);\n\n      return callback(error);\n    }\n\n    const {heapSnapshotLocation} = this;\n\n    this.transportActions.takeHeapSnapshot(heapSnapshotLocation, callback);\n  }\n\n  command(heapSnapshotLocation, callback) {\n    this.heapSnapshotLocation = heapSnapshotLocation;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = TakeHeapSnapshot;\n"
  },
  {
    "path": "lib/api/client-commands/urlHash.js",
    "content": "const ClientCommand = require('./_base-command.js');\n\n/**\n * Convenience command that adds the specified hash (i.e. url fragment) to the current value of the `launch_url` as set in `nightwatch.json`.\n *\n * @example\n * this.demoTest = function (client) {\n *   client.urlHash('#hashvalue');\n *   // or\n *   client.urlHash('hashvalue');\n * };\n *\n *\n * @method urlHash\n * @param {string} hash The hash to add/replace to the current url (i.e. the value set in the launch_url property in nightwatch.json).\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see url\n * @api protocol.navigation\n */\nclass UrlHash extends ClientCommand {\n  get returnsFullResultObject() {\n    return true;\n  }\n\n  performAction(callback) {\n    this.api.url(this.api.launchUrl + '#' + this.hash, callback);\n  }\n\n  command(hash, callback) {\n    if (hash.charAt(0) === '#') {\n      hash = hash.substring(1);\n    }\n\n    this.hash = hash;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = UrlHash;\n"
  },
  {
    "path": "lib/api/client-commands/useCss.js",
    "content": "const LocateStrategy = require('./_locateStrategy.js');\nconst Strategies = require('../../element').LocateStrategy;\n\n/**\n * Sets the locate strategy for selectors to `css selector`, therefore every following selector needs to be specified as css.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser\n *     .useCss() // we're back to CSS now\n *     .setValue('input[type=text]', 'nightwatch');\n * };\n *\n * @method useCss\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.utilities\n */\n\nclass Command extends LocateStrategy {\n  constructor() {\n    super();\n    this.strategy = Strategies.CSS_SELECTOR;\n  }\n}\n\nmodule.exports = Command;\n"
  },
  {
    "path": "lib/api/client-commands/useXpath.js",
    "content": "const LocateStrategy = require('./_locateStrategy.js');\nconst Strategies = require('../../element').LocateStrategy;\n\n/**\n * Sets the locate strategy for selectors to xpath, therefore every following selector needs to be specified as xpath.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser\n *     .useXpath() // every selector now must be xpath\n *     .click(\"//tr[@data-recordid]/span[text()='Search Text']\");\n * };\n *\n * @method useXpath\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.utilities\n */\n\nclass Command extends LocateStrategy {\n  constructor() {\n    super();\n    this.strategy = Strategies.XPATH;\n  }\n}\n\nmodule.exports = Command;\n"
  },
  {
    "path": "lib/api/client-commands/window/close.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Close the current window or tab. This can be useful when you're working with multiple windows/tabs open (e.g. an OAuth login).\n *\n * After closing a window or tab, you must switch back to a valid window handle (using `.window.switchTo()` command) in order to continue execution.\n *\n * @example\n * module.exports = {\n *  'close current window/tab': function (browser) {\n *     browser.window.close(function (result) {\n *       console.log('current window/tab closed successfully');\n *     });\n *   },\n *\n *   'close current window/tab with ES6 async/await': async function (browser) {\n *     await browser.window.close();\n *   }\n * }\n *\n * @syntax .window.close([callback])\n * @method window.close\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @exampleLink /api/closeWindow.js\n * @link /#close-window\n * @see window.open\n * @api protocol.window\n */\nclass CloseWindow extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.closeWindow(callback);\n  }\n}\n\nmodule.exports = CloseWindow;\n"
  },
  {
    "path": "lib/api/client-commands/window/fullscreen.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Set the current window state to fullscreen, similar to pressing F11 in most browsers.\n *\n * @example\n * module.exports = {\n *  'make current window fullscreen': function (browser) {\n *     browser.window.fullscreen(function () {\n *       console.log('window in fullscreen mode');\n *     });\n *   },\n *\n *   'make current window fullscreen with ES6 async/await': async function (browser) {\n *     await browser.window.fullscreen();\n *   }\n * }\n *\n * @syntax .window.fullscreen([callback])\n * @method window.fullscreen\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @link /#fullscreen-window\n * @see window.maximize\n * @see window.minimize\n * @api protocol.window\n */\nclass FullscreenWindow extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.fullscreenWindow(callback);\n  }\n}\n\nmodule.exports = FullscreenWindow;\n"
  },
  {
    "path": "lib/api/client-commands/window/getAllHandles.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Retrieve the list of all window handles available to the session.\n *\n * @example\n * module.exports = {\n *  'get all window handles': function (browser) {\n *     browser.window.getAllHandles(function (result) {\n *       console.log('available window handles are:', result.value);\n *     });\n *   },\n *\n *   'get all window handles with ES6 async/await': async function (browser) {\n *     const windowHandles = await browser.window.getAllHandles();\n *     console.log('available window handles are:', windowHandles);\n *   }\n * }\n *\n * @syntax .window.getAllHandles([callback])\n * @method window.getAllHandles\n * @param {function} callback Callback function which is called with the result value.\n * @returns {string[]} An array of all available window handles.\n * @see window.getHandle\n * @see window.switchTo\n * @link /#get-window-handles\n * @api protocol.window\n */\nclass GetAllWindowHandles extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.getAllWindowHandles(callback);\n  }\n}\n\nmodule.exports = GetAllWindowHandles;\n"
  },
  {
    "path": "lib/api/client-commands/window/getHandle.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Retrieve the current window handle.\n *\n * WebDriver does not make the distinction between windows and tabs. So, if your site opens a new tab or window, you can work with it using a window handle.\n *\n * @example\n * module.exports = {\n *  'get current window handle': function (browser) {\n *     browser.window.getHandle(function (result) {\n *       console.log('current window handle is:', result.value);\n *     });\n *   },\n *\n *   'get current window handle with ES6 async/await': async function (browser) {\n *     const windowHandle = await browser.window.getHandle();\n *     console.log('current window handle is:', windowHandle);\n *   }\n * }\n *\n * @syntax .window.getHandle([callback])\n * @method window.getHandle\n * @param {function} callback Callback function which is called with the result value.\n * @returns {string} A unique identifier representing the window handle for the current window.\n * @link /#get-window-handle\n * @see window.getHandles\n * @see window.switchTo\n * @api protocol.window\n */\nclass GetWindowHandle extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.getWindowHandle(callback);\n  }\n}\n\nmodule.exports = GetWindowHandle;\n"
  },
  {
    "path": "lib/api/client-commands/window/getPosition.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Get the coordinates of the top left corner of the current window.\n *\n * @example\n * module.exports = {\n *   'get current window position': function (browser) {\n *      browser.window.getPosition(function (result) {\n *        console.log('Position of current window:', result.value.x, result.value.y);\n *      });\n *   },\n *\n *   'get current window position using ES6 async/await': async function (browser) {\n *      const {x, y} = await browser.window.getPosition();\n *      console.log('Position of current window:', x, y);\n *   }\n * }\n *\n * @syntax .window.getPosition([callback])\n * @method window.getPosition\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {{x: number, y: number}} Coordinates representing the position of the current window.\n * @see window.getSize\n * @see window.getRect\n * @api protocol.window\n */\nclass GetWindowPosition extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.getWindowPosition(callback);\n  }\n}\n\nmodule.exports = GetWindowPosition;\n"
  },
  {
    "path": "lib/api/client-commands/window/getRect.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Fetches the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect) - size and position of the current window.\n *\n * Its JSON representation is the following:\n * - `x` - window's screenX attribute;\n * - `y` - window's screenY attribute;\n * - `width` - outerWidth attribute;\n * - `height` - outerHeight attribute.\n *\n * All attributes are in CSS pixels.\n *\n * @example\n * module.exports = {\n *   'get current window rect': function (browser) {\n *      browser.window.getRect(function (result) {\n *        console.log('Size of current window:', result.value.width, result.value.height);\n *        console.log('Position of current window:', result.value.x, result.value.y);\n *      });\n *   },\n *\n *   'get current window rect using ES6 async/await': async function (browser) {\n *      const {width, height, x, y} = await browser.window.getRect();\n *      console.log('Size of current window:', width, height);\n *      console.log('Position of current window:', x, y);\n *   }\n * }\n *\n * @syntax .window.getRect([callback])\n * @method window.getRect\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {{width: number, height: number, x: number, y: number}} Size and position of the current window.\n * @link /#get-window-rect\n * @see window.getPosition\n * @see window.getSize\n * @api protocol.window\n */\nclass GetWindowRect extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.getWindowRect(callback);\n  }\n}\n\nmodule.exports = GetWindowRect;\n"
  },
  {
    "path": "lib/api/client-commands/window/getSize.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Get the size of the current window in pixels.\n *\n * @example\n * module.exports = {\n *   'get current window size': function (browser) {\n *      browser.window.getSize(function (result) {\n *        console.log('Size of current window:', result.value.width, result.value.height);\n *      });\n *   },\n *\n *   'get current window size using ES6 async/await': async function (browser) {\n *      const {width, height} = await browser.window.getSize();\n *      console.log('Size of current window:', width, height);\n *   }\n * }\n *\n * @syntax .window.getSize([callback])\n * @method window.getSize\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {{width: number, height: number}} Size of the current window.\n * @see window.getPosition\n * @see window.getRect\n * @api protocol.window\n */\nclass GetWindowSize extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.getWindowSize(callback);\n  }\n}\n\nmodule.exports = GetWindowSize;\n"
  },
  {
    "path": "lib/api/client-commands/window/maximize.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Increases the window to the maximum available size without going full-screen.\n *\n * @example\n * module.exports = {\n *  'maximize current window': function (browser) {\n *     browser.window.maximize(function () {\n *       console.log('window maximized successfully');\n *     });\n *   },\n *\n *   'maximize current window using ES6 async/await': async function (browser) {\n *     await browser.window.maximize();\n *   }\n * }\n *\n * @syntax .window.maximize([callback])\n * @method window.maximize\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @link /#maximize-window\n * @see window.minimize\n * @see window.fullscreen\n * @api protocol.window\n */\nclass MaximizeWindow extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.maximizeWindow(callback);\n  }\n}\n\nmodule.exports = MaximizeWindow;\n"
  },
  {
    "path": "lib/api/client-commands/window/minimize.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Hides the window in the system tray. If the window happens to be in fullscreen mode, it is restored the normal state then it will be \"iconified\" - minimize or hide the window from the visible screen.\n *\n * @example\n * module.exports = {\n *  'minimize current window': function (browser) {\n *     browser.window.minimize(function () {\n *       console.log('window minimized successfully');\n *     });\n *   },\n *\n *   'minimize current window using ES6 async/await': async function (browser) {\n *     await browser.window.minimize();\n *   }\n * }\n *\n * @syntax .window.minimize([callback])\n * @method window.minimize\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @link /#minimize-window\n * @see window.maximize\n * @see window.fullscreen\n * @api protocol.window\n */\nclass MinimizeWindow extends ClientCommand {\n  performAction(callback) {\n    this.transportActions.minimizeWindow(callback);\n  }\n}\n\nmodule.exports = MinimizeWindow;\n"
  },
  {
    "path": "lib/api/client-commands/window/open.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Opens a new tab (default) or a separate new window, and changes focus to the newly opened tab/window.\n *\n * This command is only available for W3C Webdriver compatible browsers.\n *\n * @example\n * module.exports = {\n *  'open a new tab/window': function (browser) {\n *     // open a new tab (default)\n *     browser.window.open(function () {\n *       console.log('new tab opened successfully');\n *     });\n *\n *     // open a new window\n *     browser.window.open('window', function () {\n *       console.log('new window opened successfully');\n *     });\n *   },\n *\n *   'open a new tab/window ES6 async demo Test': async function (browser) {\n *     // open a new tab (default)\n *     await browser.window.open();\n *\n *     // open a new window\n *     await browser.window.open('window');\n *   }\n * }\n *\n * @syntax .window.open([callback])\n * @syntax .window.open(type, [callback])\n * @method window.open\n * @param {string} [type] Can be either \"tab\" or \"window\", with \"tab\" set as default if none is specified.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @link /#new-window\n * @see window.close\n * @see window.switchTo\n * @api protocol.window\n */\nclass OpenNewWindow extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  static get namespacedAliases() {\n    return 'window.openNew';\n  }\n\n  performAction(callback) {\n    const {windowType} = this;\n\n    this.transportActions.openNewWindow(windowType, callback);\n  }\n\n  command(type = 'tab', callback) {\n    if (typeof type == 'function' && callback === undefined) {\n      callback = arguments[0];\n      type = 'tab';\n    }\n\n    this.windowType = type;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = OpenNewWindow;\n"
  },
  {
    "path": "lib/api/client-commands/window/setPosition.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Set the position of the current window - move the window to the chosen position.\n *\n * @example\n * module.exports = {\n *   'set current window position': function (browser) {\n *      // Move the window to the top left of the primary monitor\n *      browser.window.setPosition(0, 0, function (result) {\n *        console.log('window moved successfully');\n *      });\n *   },\n *\n *   'set current window position using ES6 async/await': async function (browser) {\n *      // Move the window to the top left of the primary monitor\n *      await browser.window.setPosition(0, 0);\n *   }\n * }\n *\n * @syntax .window.setPosition(x, y, [callback])\n * @method window.setPosition\n * @param {number} x New x-coordinate of the top-left corner of the window.\n * @param {number} y New y-coordinate of the top-left corner of the window.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see window.setSize\n * @see window.setRect\n * @api protocol.window\n */\nclass SetWIndowPosition extends ClientCommand {\n  performAction(callback) {\n    const {xOffset, yOffset} = this;\n\n    this.transportActions.setWindowPosition(xOffset, yOffset, callback);\n  }\n\n  command(x, y, callback) {\n    if (typeof x !== 'number' || typeof y !== 'number') {\n      throw new Error('Coordinates passed to .window.getPosition() must be of type number.');\n    }\n\n    this.xOffset = x;\n    this.yOffset = y;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetWIndowPosition;\n"
  },
  {
    "path": "lib/api/client-commands/window/setRect.js",
    "content": "const ClientCommand = require('../_base-command.js');\nconst Utils = require('../../../utils/index.js');\n\n/**\n * Change the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect) - size and position of the current window.\n *\n * Its JSON representation is the following:\n * - `x` - window's screenX attribute;\n * - `y` - window's screenY attribute;\n * - `width` - outerWidth attribute;\n * - `height` - outerHeight attribute.\n *\n * All attributes are in CSS pixels.\n *\n * To change the window rect, you can either specify `width` and `height` together, `x` and `y` together, or all properties together.\n *\n * @example\n * module.exports = {\n *   'set current window rect': function (browser) {\n *      // Change the screenX and screenY attributes of the window rect.\n *      browser.window.setRect({x: 500, y: 500});\n *\n *      // Change the outerWidth and outerHeight attributes of the window rect.\n *      browser.window.setRect({width: 600, height: 300});\n *   },\n *\n *   'set current window rect using ES6 async/await': async function (browser) {\n *      // Change all attributes of the window rect at once.\n *      await browser.window.setRect({\n *        width: 600,\n *        height: 300,\n *        x: 100,\n *        y: 100\n *      });\n *   }\n * }\n *\n * @syntax .window.setRect({width, height, x, y}, [callback])\n * @method window.setRect\n * @param {Object} options An object specifying either `width` and `height`, `x` and `y`, or all together to set properties for the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect).\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @link /#set-window-rect\n * @see window.setPosition\n * @see window.setSize\n * @api protocol.window\n */\nclass SetWindowRect extends ClientCommand {\n  performAction(callback) {\n    const {windowOptions} = this;\n\n    this.transportActions.setWindowRect(windowOptions, callback);\n  }\n\n  command(options, callback) {\n    const {width, height, x, y} = options;\n\n    if (!Utils.isUndefined(width) || !Utils.isUndefined(height)) {\n      // either of width and height is defined, so both must be defined\n      if (Utils.isUndefined(width) || Utils.isUndefined(height)) {\n        throw new Error('Attributes \"width\" and \"height\" must be specified together when using .window.setRect() command.');\n      }\n\n      if (!Utils.isNumber(width)) {\n        throw new Error(`Width argument passed to .window.setRect() must be a number; received: ${typeof width} (${width}).`);\n      }\n\n      if (!Utils.isNumber(height)) {\n        throw new Error(`Height argument passed to .window.setRect() must be a number; received: ${typeof height} (${height}).`);\n      }\n    }\n\n    if (!Utils.isUndefined(x) || !Utils.isUndefined(y)) {\n      // either of x and y is defined, so both must be defined\n      if (Utils.isUndefined(x) || Utils.isUndefined(y)) {\n        throw new Error('Attributes \"x\" and \"y\" must be specified together when using .window.setRect() command.');\n      }\n\n      if (!Utils.isNumber(x)) {\n        throw new Error(`X position argument passed to .window.setRect() must be a number; received: ${typeof x} (${x}).`);\n      }\n\n      if (!Utils.isNumber(y)) {\n        throw new Error(`Y position argument passed to .window.setRect() must be a number; received: ${typeof y} (${y}).`);\n      }\n    }\n\n    this.windowOptions = options;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetWindowRect;\n"
  },
  {
    "path": "lib/api/client-commands/window/setSize.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Set the size of the current window in CSS pixels.\n *\n * @example\n * module.exports = {\n *   'set current window size': function (browser) {\n *      browser.window.setSize(1024, 768, function (result) {\n *        console.log('window resized successfully');\n *      });\n *   },\n *\n *   'set current window size using ES6 async/await': async function (browser) {\n *      await browser.window.setSize(1024, 768);\n *   }\n * }\n *\n * @syntax .window.setSize(width, height, [callback])\n * @method window.setSize\n * @param {number} width The new window width in CSS pixels.\n * @param {number} height The new window height in CSS pixels.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see window.setPosition\n * @see window.setRect\n * @api protocol.window\n */\nclass SetWindowSize extends ClientCommand {\n  static get namespacedAliases() {\n    return 'window.resize';\n  }\n\n  performAction(callback) {\n    const {width, height} = this;\n\n    this.transportActions.setWindowSize(width, height, callback);\n  }\n\n  command(width, height, callback) {\n    if (typeof width !== 'number' || typeof height !== 'number') {\n      throw new Error('First two arguments passed to .window.getPosition() must be of type number.');\n    }\n\n    this.width = width;\n    this.height = height;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SetWindowSize;\n"
  },
  {
    "path": "lib/api/client-commands/window/switchTo.js",
    "content": "const ClientCommand = require('../_base-command.js');\n\n/**\n * Change focus to another window.\n *\n * The window to change focus to must be specified by its server assigned window handle. To find out the window handle, use `window.getAllHandles()` command.\n *\n * @example\n * module.exports = {\n *  'switch to another window': function (browser) {\n *     browser\n *       .navigateTo('https://nightwatchjs.org/__e2e/window/')\n *       .click('#openWindowBttn')\n *       .waitUntil(function () {\n *         // wait until window handle for the new window is available\n *         return new Promise((resolve) => {\n *           browser.window.getAllHandles(function (result) {\n *             resolve(result.value.length === 2);\n *           });\n *         });\n *       })\n *       .perform(async function () {\n *         const originalWindow = await browser.window.getHandle();\n *         const allWindows = await browser.window.getAllHandles();\n *\n *         // loop through to find the new window handle\n *         for (const windowHandle of allWindows) {\n *           if (windowHandle !== originalWindow) {\n *             await browser.window.switchTo(windowHandle);\n *             break;\n *           }\n *         }\n *\n *         const currentWindow = await browser.window.getHandle();\n *         browser.assert.notEqual(currentWindow, originalWindow);\n *       });\n *   },\n *\n *   'switch to another window with ES6 async/await': async function (browser) {\n *     await browser.navigateTo('https://nightwatchjs.org/__e2e/window/');\n *     await browser.click('#openWindowBttn');\n *\n *     // wait until window handle for the new window is available\n *     await browser.waitUntil(async function () {\n *       const windowHandles = await browser.window.getAllHandles();\n *\n *       return windowHandles.length === 2;\n *     });\n *\n *     const originalWindow = await browser.window.getHandle();\n *     const allWindows = await browser.window.getAllHandles();\n *\n *     // loop through available windows to find the new window handle\n *     for (const windowHandle of allWindows) {\n *       if (windowHandle !== originalWindow) {\n *         await browser.window.switchTo(windowHandle);\n *         break;\n *       }\n *     }\n *\n *     const currentWindow = await browser.window.getHandle();\n *     await browser.assert.notEqual(currentWindow, originalWindow);\n *   }\n * }\n *\n * @syntax .window.switchTo(windowHandle, [callback])\n * @method window.switchTo\n * @param {string} windowHandle The server assigned window handle, should be one of the strings that was returned in a call to `.window.getAllHandles()`.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see window.getHandle\n * @see window.getAllHandles\n * @link /#switch-to-window\n * @api protocol.window\n */\nclass SwitchToWindow extends ClientCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  static get namespacedAliases() {\n    return 'window.switch';\n  }\n\n  performAction(callback) {\n    const {windowHandle} = this;\n\n    this.transportActions.switchToWindow(windowHandle, callback);\n  }\n\n  command(windowHandle, callback) {\n    if (typeof windowHandle !== 'string') {\n      throw new Error(`windowHandle argument passed to .window.switchTo() must be a string; received: ${typeof windowHandle} (${windowHandle}).`);\n    }\n\n    this.windowHandle = windowHandle;\n\n    return super.command(callback);\n  }\n}\n\nmodule.exports = SwitchToWindow;\n"
  },
  {
    "path": "lib/api/client-commands/within.js",
    "content": "/**\n * Returns a context for the given element which can be used for querying child elements.\n *\n * @example\n * describe('example using within()', function() {\n *\n *   it('click a button within the element', async function(browser) {\n *     const context = browser.within('#weblogin');\n *     await context.click('button');\n *   });\n * })\n *\n * @method within\n * @syntax browser.within('#element').click('button');\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @api protocol.elements\n * @since 2.5.5\n */\nmodule.exports = class WithinAbstract {\n  static get allowOverride() {\n    return true;\n  }\n};\n"
  },
  {
    "path": "lib/api/element-commands/_baseElementCommand.js",
    "content": "const {WebElement} = require('selenium-webdriver');\nconst ElementCommand = require('../../element').Command;\nconst Utils = require('../../utils');\nconst {Logger, filterStackTrace} = Utils;\n\nclass BaseElementCommand extends ElementCommand {\n  get w3c_deprecated() {\n    return false;\n  }\n\n  static getErrorMessage(response = {}) {\n    const {value, error = ''} = response;\n\n    if (value && value.error) {\n      return value.error;\n    }\n\n    return error;\n  }\n\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get retryOnFailure() {\n    return true;\n  }\n\n  get elementProtocolAction() {\n    return null;\n  }\n\n  static get isTraceable() {\n    return false;\n  }\n\n  setOptionsFromSelector() {\n    this.abortOnFailure = this.api.globals.abortOnElementLocateError;\n\n    super.setOptionsFromSelector();\n  }\n\n  async findElementAction({cacheElementId = true} = {}) {\n    if (WebElement.isId(this.selector)) {\n      return {\n        value: this.selector,\n        status: 0,\n        result: {}\n      };\n    }\n\n    if ((this.selector instanceof Promise) && this.selector['@nightwatch_element']) {\n      this.__element = await this.selector;\n    }\n\n    return this.findElement({cacheElementId});\n  }\n\n  setupActions() {\n    const isResultStale = (response) => {\n      const result = this.transport.isRetryableElementError(response);\n\n      return result;\n    };\n    const validate = (result) => this.isResultSuccess(result);\n    const successHandler = (result) => this.complete(null, result);\n\n    this.elementCommandRetries = 0;\n    this.maxElementCommandRetries = this.settings.element_command_retries;\n\n    this.executor\n      .queueAction({\n        action: (opts) => this.findElementAction(opts),\n        retryOnSuccess: this.retryOnSuccess,\n        shouldRetryOnError: (response) => {\n          return !this.transport.invalidWindowReference(response.result || response);\n        },\n        validate,\n        errorHandler: err => {\n          const result = err.response || {};\n\n          if (this.suppressNotFoundErrors) {\n            return this.complete(null, result);\n          }\n\n          let error;\n          if (result.error && result.error.name === 'NoSuchElementError') {\n            error = result.error;\n          } else {\n            error = this.noSuchElementError(err);\n            error.response = result;\n          }\n\n          return this.elementLocateError(error);\n        }\n      })\n      .queueAction({\n        action: (response) => this.elementFound(response),\n        retryOnSuccess: this.retryOnValidActionResult,\n        retryOnFailure: this.retryOnFailure,\n        validate: (result) => this.transport.isResultSuccess(result),\n        isResultStale,\n        successHandler,\n        errorHandler: (err) => this.handleElementError(err)\n      });\n  }\n\n  elementNotFound(err) {\n    return this.handleElementError(err);\n  }\n\n  shouldRetryElementCommand(result) {\n    if (this.transport.isRetryableElementError(result) && this.elementCommandRetries < this.maxElementCommandRetries) {\n      return true;\n    }\n\n    return false;\n  }\n\n  async protocolAction() {\n    if (!this.elementProtocolAction) {\n      throw new Error('Define elementProtocolAction.');\n    }\n\n    const result = await this.executeProtocolAction(this.elementProtocolAction, this.args);\n\n    this.elementCommandRetries++;\n\n    // if (this.shouldRetryElementCommand(result)) {\n    //   this.__retryOnFailure = true;\n    //   this.elementCommandRetries++;\n    // } else {\n    //   //this.__retryOnFailure = false;\n    // }\n\n    if (result && result.error instanceof Error) {\n      this.transport.registerLastError(result.error, this.elementCommandRetries);\n    }\n\n    return result;\n  }\n\n  handleElementError(err) {\n    const showRegisterError = this.transport.shouldRegisterError(err);\n\n    let originalErrorMessage;\n    if (err instanceof Error) {\n      originalErrorMessage = err.message;\n    } else {\n      originalErrorMessage = BaseElementCommand.getErrorMessage(err.response);\n    }\n\n    err.message = `An error occurred while running .${this.commandName}() command on <${this.element.toString()}>: ${originalErrorMessage}`;\n    if (err.response) {\n      err.detailedErr = JSON.stringify(err.response);\n    }\n\n    err.stack = filterStackTrace(this.stackTrace);\n\n    if (showRegisterError) {\n      Logger.error(err);\n\n      this.reporter.registerTestError(err);\n      err.registered = true;\n    }\n\n    const {message, stack} = err;\n    const callbackResult = {\n      status: -1,\n      value: {\n        error: message,\n        message,\n        stack\n      }\n    };\n\n    if (this.abortOnFailure) {\n      return this.complete(err, err.response || {});\n    }\n\n    return this.complete(null, callbackResult);\n  }\n}\n\nmodule.exports = BaseElementCommand;\n"
  },
  {
    "path": "lib/api/element-commands/_waitFor.js",
    "content": "const Utils = require('../../utils');\nconst {AssertionRunner} = require('../../assertion');\nconst {LocateStrategy, Command: ElementCommand} = require('../../element');\n\n/*!\n * Base class for waitForElement commands. It provides a command\n * method and element* methods to be overridden by subclasses\n *\n * @constructor\n */\nclass WaitForElement extends ElementCommand {\n  get retryOnSuccess() {\n    return false;\n  }\n\n  static get rejectNodeOnAbortFailure() {\n    return true;\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  static isElementVisible(result) {\n    return result.value === true;\n  }\n\n  constructor(opts) {\n    super(opts);\n\n    this.expectedValue = 'found';\n  }\n\n  validateArgsCount() {\n    if (LocateStrategy.isValid(this.args[0]) && (Utils.isString(this.args[1]) || ElementCommand.isSelectorObject(this.args[1]))) {\n      this.setStrategyFromArgs();\n    }\n  }\n\n  setupActions() {\n    const validate = (result) => this.isResultSuccess(result);\n    const successHandler = (result) => this.elementFound(result);\n\n    this.executor\n      .queueAction({\n        action: () => this.findElement({cacheElementId: false}),\n        retryOnSuccess: this.retryOnSuccess,\n        retryOnFailure: !this.retryOnSuccess,\n        validate,\n        successHandler,\n        errorHandler: (err) => {\n          if (err.name !== 'TimeoutError') {\n            throw err;\n          }\n\n          const {response} = err;\n\n          if (response && response.error instanceof Error) {\n            if (response.error.name === 'NoSuchElementError') {\n              return this.elementNotFound(response);\n            }\n\n            this.reporter.registerTestError(response.error);\n\n            return this.fail(response, 'error while locating the element', this.expectedValue, 'Timed out while waiting for element <%s> for %d milliseconds');\n          }\n\n\n          if (response && response.value) {\n            return this.elementFound(response);\n          }\n\n          return this.elementNotFound(response);\n        }\n      });\n  }\n\n  /*!\n   * The public command function which will be called by the test runner. Arguments can be passed in a variety of ways.\n   *\n   * The custom message always is last and the callback is always before the message or last if a message is not passed.\n   *\n   * The second argument is always the time in milliseconds. The third argument can be either of:\n   * - abortOnFailure: this can overwrite the default behaviour of aborting the test if the condition is not met within the specified time\n   * - rescheduleInterval: this can overwrite the default polling interval (currently 500ms)\n   * The above can be supplied also together, in which case the rescheduleInterval is specified before the abortOnFailure.\n   *\n   * Some of the multiple usage possibilities:\n   * ---------------------------------------------------------------------------\n   * - with no arguments; in this case a global default timeout is used\n   *  waitForElement('body');\n   *\n   * - with a global default timeout and a callback\n   *  waitForElement('body', function() {});\n   *\n   * - with a global default timeout, a callback, and a custom message\n   *  waitForElement('body', function() {}, 'test message');\n   *\n   * - with a global default timeout a custom message\n   *  waitForElement('body', 'test message');\n   *\n   * - with only the timeout\n   *  waitForElement('body', 500);\n   *\n   * - with a timeout and a custom message\n   *  waitForElement('body', 500, 'test message);\n   *\n   * - with a timeout and a callback\n   *  waitForElement('body', 500, function() { .. });\n   *\n   * - with a timeout and a custom abortOnFailure\n   *  waitForElement('body', 500, true);\n   *\n   * - with a timeout, a custom abortOnFailure, and a custom message\n   *  waitForElement('body', 500, true, 'test message');\n   *\n   * - with a timeout, a custom abortOnFailure, and a callback\n   *  waitForElement('body', 500, true, function() { .. });\n   *\n   * - with a timeout, a custom abortOnFailure, a callback and a custom message\n   *  waitForElement('body', 500, true, function() { .. }, 'test message');\n   *\n   * - with a timeout, a custom reschedule interval, and a callback\n   *  waitForElement('body', 500, 100, function() { .. });\n   *\n   * - with a timeout, a custom rescheduleInterval, and a custom abortOnFailure\n   *  waitForElement('body', 500, 100, false);\n   *\n   *\n   * @param {string} selector\n   * @param {number|function|string} milliseconds\n   * @param {function|boolean|string|number} callbackOrAbort\n   * @returns {WaitForElement}\n   */\n  setArguments() {\n    super.setArguments();\n\n    let rescheduleInterval;\n    ////////////////////////////////////////////////////////////////////////////\n    // custom timeout value\n    //\n    // waitForElement('body', 100);\n    ////////////////////////////////////////////////////////////////////////////\n    if (Utils.isNumber(this.args[0])) {\n      this.setMilliseconds(this.args[0]);\n    }\n\n    ////////////////////////////////////////////////\n    // DEPRECATED\n    // backwards compatibility\n    ////////////////////////////////////////////////\n    if (Utils.isBoolean(this.args[1])) {\n      ////////////////////////////////////////////////\n      // The command was called with a custom abortOnFailure:\n      //\n      // waitForElement('body', 500, false);\n      ////////////////////////////////////////////////\n      this.abortOnFailure = this.args[1];\n      // eslint-disable-next-line brace-style\n    }\n    ////////////////////////////////////////////////\n    // The command was called with a custom timeout and rescheduleInterval:\n    //\n    // waitForElement('body', 500, 100);\n    ////////////////////////////////////////////////\n    else if (Utils.isNumber(this.args[1])) {\n      rescheduleInterval = this.args[1];\n\n      ////////////////////////////////////////////////\n      // The command was called with a custom timeout, rescheduleInterval, and custom abortOnFailure:\n      //\n      // waitForElement('body', 500, 100, false);\n      // waitForElement('body', 500, 100, false, function() {});\n      ////////////////////////////////////////////////\n      if (Utils.isBoolean(this.args[2])) {\n        this.abortOnFailure = this.args[2];\n      }\n    }\n\n    if (rescheduleInterval) {\n      this.setRescheduleInterval(rescheduleInterval);\n    }\n  }\n\n  pass(result, defaultMsg, timeMs) {\n    this.message = this.formatMessage(defaultMsg, timeMs);\n\n    return this.assert({\n      result,\n      passed: true,\n      err: {\n        expected: this.expectedValue\n      }\n    });\n  }\n\n  fail(result, actual, expected, defaultMsg) {\n    this.message = this.formatMessage(defaultMsg);\n\n    return this.assert({\n      result,\n      passed: false,\n      err: {\n        actual,\n        expected\n      }\n    });\n  }\n\n  assert({result, passed, err}) {\n    this.elapsedTime = this.executor.elapsedTime;\n\n    const {reporter} = this.client;\n    const {elapsedTime, message, abortOnFailure, stackTrace} = this;\n    const runner = new AssertionRunner({\n      passed,\n      err,\n      message,\n      abortOnFailure,\n      stackTrace,\n      reporter,\n      elapsedTime\n    });\n\n    return runner.run(result)\n      .catch(err => (err))\n      .then(err => {\n        if (Utils.isObject(result.value) && !Array.isArray(result.value)) {\n          result.value = [result.value];\n        }\n\n        if (err instanceof Error) {\n          err.abortOnFailure = this.abortOnFailure;\n          err.waitFor = true;\n\n          return this.complete(err, result);\n        }\n\n        return this.complete(null, result);\n      });\n  }\n\n  /**\n   * @param {string} defaultMsg\n   * @param {number} [timeMs]\n   * @returns {string}\n   */\n  formatMessage(defaultMsg, timeMs) {\n    return Utils.format(this.message || defaultMsg, this.element.selector, timeMs || this.ms);\n  }\n\n  elementNotFound(result) {\n    const defaultMsg = 'Timed out while waiting for element <%s> to be present for %d milliseconds.';\n\n    return this.fail(result, 'not found', this.expectedValue, defaultMsg);\n  }\n}\n\nmodule.exports = WaitForElement;\n"
  },
  {
    "path": "lib/api/element-commands/_waitForDisplayed.js",
    "content": "const WaitForElement = require('./_waitFor.js');\n\nclass WaitForDisplayed extends WaitForElement {\n  protocolAction() {\n    return this.executeProtocolAction('isElementDisplayed');\n  }\n\n  shouldRetryAction(elementVisible) {\n    throw new Error('Override');\n  }\n\n  setupActions() {\n    const isResultStale = (result) => {\n      const errorResponse = this.transport.getErrorResponse(result);\n\n      return this.transport.staleElementReference(errorResponse);\n    };\n    const validate = (result) => this.isResultSuccess(result);\n    const successHandler = (result) => this.protocolActionHandler(result);\n\n    this.executor\n      .queueAction({\n        action: () => this.findElement({cacheElementId: false}),\n        retryOnSuccess: this.retryOnSuccess,\n        validate,\n        errorHandler: (err) => {\n          if (err.name !== 'TimeoutError') {\n            return err;\n          }\n\n          return this.elementNotFound(err.response);\n        }\n      })\n      .queueAction({\n        action: (response) => this.elementFound(response),\n        retryOnSuccess: (result) => {\n          const elementVisible = WaitForElement.isElementVisible(result);\n\n          return this.shouldRetryAction(elementVisible);\n        },\n        validate,\n        isResultStale,\n        successHandler,\n        errorHandler: (err) => {\n          if (err.name !== 'TimeoutError') {\n            return err;\n          }\n\n          return this.complete(err, {});\n        }\n      });\n  }\n\n  protocolActionHandler(result) {\n    if (WaitForElement.isElementVisible(result)) {\n      return this.elementVisible(result);\n    }\n\n    return this.elementNotVisible(result);\n  }\n\n  elementVisible(response) {}\n  elementNotVisible(response) {}\n}\n\nmodule.exports = WaitForDisplayed;\n"
  },
  {
    "path": "lib/api/element-commands/check.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Will check, by clicking, on a checkbox or radio input if it is not already checked.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.check('input[type=checkbox]:not(:checked)');\n *\n *     browser.check('input[type=checkbox]:not(:checked)', function(result) {\n *       console.log('Check result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.check('css selector', 'input[type=checkbox]:not(:checked)');\n *\n *     // with selector object - see https://nightwatchjs.org/guide#element-properties\n *     browser.check({\n *       selector: 'input[type=checkbox]:not(:checked)',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     });\n *\n *     browser.check({\n *       selector: 'input[type=checkbox]:not(:checked)',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.check('input[type=checkbox]:not(:checked)');\n *     console.log('Check result', result);\n *   }\n * }\n *\n * @method check\n * @syntax .check(selector, [callback])\n * @syntax .check(using, selector, [callback])\n * @syntax browser.element(selector).check()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string} selector The CSS/Xpath selector used to locate the element.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinteraction\n */\nclass CheckElement extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'checkElement';\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  async protocolAction() {\n    return this.executeProtocolAction(this.elementProtocolAction);\n  }\n}\n\nmodule.exports = CheckElement;\n"
  },
  {
    "path": "lib/api/element-commands/clearValue.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Clear a textarea or a text input element's value.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.clearValue('#login input[type=text]');\n *\n *     browser.clearValue('#login input[type=text]', function(result) {\n *       console.log('clearValue result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.clearValue('css selector', '#login input[type=text]');\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.clearValue({\n *       selector: '#login input[type=text]',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     });\n *\n *     browser.clearValue({\n *       selector: '#login input[type=text]',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   }\n * }\n *\n * @method clearValue\n * @syntax browser.clearValue('&lt;SELECTOR&gt;', function (result) { }])\n * @syntax\n * // using global element()\n * browser.clearValue(element('&lt;SELECTOR&gt;'))\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinteraction\n * @link /#dfn-element-clear\n */\nclass ClearValue extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'clearElementValue';\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n}\n\nmodule.exports = ClearValue;\n"
  },
  {
    "path": "lib/api/element-commands/click.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Simulates a click event on the given DOM element. The element is scrolled into view if it is not already pointer-interactable. See the WebDriver specification for <a href=\"https://www.w3.org/TR/webdriver/#element-interactability\" target=\"_blank\">element interactability</a>.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.click('#main ul li a.first');\n *\n *     browser.click('#main ul li a.first', function(result) {\n *       console.log('Click result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.click('css selector', '#main ul li a.first');\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.click({\n *       selector: '#main ul li a',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     });\n *\n *     browser.click({\n *       selector: '#main ul li a.first',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.click('#main ul li a.first');\n *     console.log('Click result', result);\n *   }\n * }\n *\n * @method click\n * @syntax .click(selector, [callback])\n * @syntax .click(using, selector, [callback])\n * @syntax browser.element(selector).click()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string} selector The CSS/Xpath selector used to locate the element.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinteraction\n * @link /#dfn-element-click\n */\nclass ClickElement extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'clickElement';\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  async protocolAction() {\n    if (this.api.isSafari() && this.api.isIOS()) {\n      return this.executeProtocolAction('clickElementWithJS');\n    }\n\n    return this.executeProtocolAction(this.elementProtocolAction);\n  }\n}\n\nmodule.exports = ClickElement;\n"
  },
  {
    "path": "lib/api/element-commands/clickAndHold.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Move to the element and click (without releasing) in the middle of the given element.\n *\n * @example\n * module.exports = {\n *   demoTest() {\n *     browser.clickAndHold('#main ul li a.first');\n *\n *     browser.clickAndHold('#main ul li a.first', function(result) {\n *       console.log('Click result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.clickAndHold('css selector', '#main ul li a.first');\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.clickAndHold({\n *       selector: '#main ul li a',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     });\n *\n *     browser.clickAndHold({\n *       selector: '#main ul li a.first',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   },\n *\n *   demoTestAsync: async function() {\n *     const result = await browser.clickAndHold('#main ul li a.first');\n *     console.log('Right click result', result);\n *   }\n * }\n *\n * @method clickAndHold\n * @syntax .clickAndHold(selector, [callback])\n * @syntax .clickAndHold(using, selector, [callback])\n * @syntax browser.element(selector).clickAndHold()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string} selector The CSS/Xpath selector used to locate the element.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinteraction\n * @see https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#click-and-hold\n * @since 2.0.0\n */\nclass ClickAndHold extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'pressAndHold';\n  }\n}\n\nmodule.exports = ClickAndHold;\n"
  },
  {
    "path": "lib/api/element-commands/doubleClick.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Move to the element and peforms a double-click in the middle of the element.\n *\n * @example\n * module.exports = {\n *   demoTest() {\n *     browser.doubleClick('#main ul li a.first');\n *\n *     browser.doubleClick('#main ul li a.first', function(result) {\n *       console.log('double click result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.doubleClick('css selector', '#main ul li a.first');\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.doubleClick({\n *       selector: '#main ul li a',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     });\n *\n *     browser.doubleClick({\n *       selector: '#main ul li a.first',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   },\n *\n *   demoTestAsync: async function() {\n *     const result = await browser.doubleClick('#main ul li a.first');\n *     console.log('double click result', result);\n *   }\n * }\n *\n * @method doubleClick\n * @syntax .doubleClick(selector, [callback])\n * @syntax .doubleClick(using, selector, [callback])\n * @syntax browser.element(selector).doubleClick()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string} selector The CSS/Xpath selector used to locate the element.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinteraction\n * @see https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#double-click\n */\nclass doubleClick extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'doubleClick';\n  }\n}\n\nmodule.exports = doubleClick;\n"
  },
  {
    "path": "lib/api/element-commands/dragAndDrop.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Drag an element to the given position or destination element.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.dragAndDrop('#main', {x: 100, y:100})\n *   }\n *\n *   // using an Element ID as a destination\n *   demoTestAsync: async function(browser) {\n *     const destination = await browser.findElement('#upload');\n *     browser.dragAndDrop('#main', destination.getId());\n *   }\n * }\n *\n * @method dragAndDrop\n * @syntax .dragAndDrop(selector, destination, callback)\n * @syntax .dragAndDrop(using, selector, destination, callback)\n * @syntax browser.element(selector).dragAndDrop(coordinates)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://w3c.github.io/webdriver/#capabilities)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](/guide/using-nightwatch/finding-and-interacting-with-elements.html#element-properties).\n * @param {string} destination Either another element to drag to (will drag to the center of the element), or an {x, y} object specifying the offset to drag by, in pixels.\n * @param {function} callback Callback function which is called with the result value; not required if using `await` operator.\n * @returns {*} null\n */\nclass DragElement extends BaseElementCommand {\n  get extraArgsCount() {\n    return 1;\n  }\n\n  get elementProtocolAction() {\n    return 'dragElement';\n  }\n}\n\nmodule.exports = DragElement;\n"
  },
  {
    "path": "lib/api/element-commands/findElement.js",
    "content": "/**\n * Search for an elements on the page, starting from the document root. The located element will be returned as web element JSON object (with an added .getId() convenience method).\n * First argument is the element selector, either specified as a string or as an object (with 'selector' and 'locateStrategy' properties).\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     const resultElement = await browser.findElement('.features-container li:first-child');\n *\n *     console.log('Element Id:', resultElement.getId());\n *   },\n *\n *\n * @link /#find-element\n * @syntax browser.findElement(selector, callback)\n * @syntax await browser.findElement(selector);\n * @param {string} selector The search target.\n * @param {function} [callback] Callback function to be invoked with the result when the command finishes.\n * @since 1.7.0\n * @api protocol.elements\n */\nconst FindElements = require('./findElements.js');\n\nmodule.exports = class FindElement extends FindElements {\n  async elementFound(response) {\n    if (response && response.value) {\n      const elementId = this.transport.getElementId(response.value);\n\n      response.value = Object.assign(response.value, {\n        get getId() {\n          return function() {\n            return elementId;\n          };\n        }\n      });\n    }\n\n    return response;\n  }\n\n  findElementAction() {\n    return this.findElement();\n  }\n};\n"
  },
  {
    "path": "lib/api/element-commands/findElements.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Search for multiple elements on the page, starting from the document root. The located elements will be returned as web element JSON objects (with an added .getId() convenience method).\n * First argument is the element selector, either specified as a string or as an object (with 'selector' and 'locateStrategy' properties).\n *\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     const resultElements = await browser.findElements('.features-container li');\n *\n *     resultElements.forEach(item => console.log('Element Id:', item.getId()));\n *   },\n *\n *\n * @link /#find-elements\n * @syntax browser.findElements(selector, callback)\n * @syntax await browser.findElements(selector);\n * @param {string} selector The search target.\n * @param {function} [callback] Callback function to be invoked with the result when the command finishes.\n * @since 1.7.0\n * @api protocol.elements\n */\nmodule.exports = class Elements extends BaseElementCommand {\n  async elementFound(response) {\n    if (response && Array.isArray(response.value)) {\n      response.value = response.value.map(entry => {\n        const elementId = this.transport.getElementId(entry);\n\n        return Object.assign(entry, {\n          get getId() {\n            return function() {\n              return elementId;\n            };\n          }\n        });\n      });\n    }\n\n    return response;\n  }\n\n  findElementAction() {\n    return this.findElement({returnSingleElement: false});\n  }\n\n  async complete(err, response) {\n    const result = await super.complete(err, response);\n    if (result instanceof Error) {\n      return result;\n    }\n\n    return result;\n  }\n\n};\n"
  },
  {
    "path": "lib/api/element-commands/getAccessibleName.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Returns the computed WAI-ARIA label of an element.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getAccessibleName('*[name=\"search\"]', function(result) {\n *       this.assert.equal(typeof result, 'object);\n *       this.assert.equal(result.value, 'search input');\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getAccessibleName('css selector', '*[name=\"search\"]', function(result) {\n *       console.log('getAccessibleName result', result.value);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getAccessibleName({\n *       selector: '*[name=\"search\"]',\n *       index: 1\n *     }, function(result) {\n *       console.log('getAccessibleName result', result.value);\n *     });\n *\n *     browser.getAccessibleName({\n *       selector: '*[name=\"search\"]',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     }, function(result) {\n *       console.log('getAccessibleName result', result.value);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getAccessibleName('*[name=\"search\"]');\n *     console.log('getAccessibleName result', result);\n *   }\n * }\n *\n * @method getAccessibleName\n * @syntax .getAccessibleName(selector, callback)\n * @syntax .getAccessibleName(using, selector, callback)\n * @syntax browser.element(selector).getAccessibleName()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string} selector The CSS/Xpath selector used to locate the element.\n * @param {function} callback Callback function which is called with the result value.\n * @returns {string} The computed WAI-ARIA label of element.\n * @link /#dfn-get-computed-label\n * @api protocol.elementstate\n */\nclass GetAccessibleName extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'getElementAccessibleName';\n  }\n}\n\nmodule.exports = GetAccessibleName;\n"
  },
  {
    "path": "lib/api/element-commands/getAriaRole.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Returns the computed WAI-ARIA role of an element.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getAriaRole('*[name=\"search\"]', function(result) {\n *       this.assert.equal(typeof result, 'object');\n *       this.assert.equal(result.value, 'combobox');\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getAriaRole('css selector', '*[name=\"search\"]', function(result) {\n *       console.log('getAriaRole result', result.value);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getAriaRole({\n *       selector: '*[name=\"search\"]',\n *       index: 1\n *     }, function(result) {\n *       console.log('getAriaRole result', result.value);\n *     });\n *\n *     browser.getAriaRole({\n *       selector: '*[name=\"search\"]',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     }, function(result) {\n *       console.log('getAriaRole result', result.value);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getAriaRole('*[name=\"search\"]');\n *     console.log('getAriaRole result', result);\n *   }\n * }\n *\n * @method getAriaRole\n * @syntax .getAriaRole(selector, callback)\n * @syntax .getAriaRole(using, selector, callback)\n * @syntax browser.element(selector).getAriaRole()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string} selector The CSS/Xpath selector used to locate the element.\n * @param {function} callback Callback function which is called with the result value.\n * @returns {string} The computed WAI-ARIA role of element.\n * @link /#dfn-get-computed-role\n * @api protocol.elementstate\n */\nclass GetAriaRole extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'getElementAriaRole';\n  }\n}\n\nmodule.exports = GetAriaRole;\n"
  },
  {
    "path": "lib/api/element-commands/getAttribute.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Retrieve the value of an attribute for a given DOM element.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getAttribute('#main ul li a.first', 'href', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getAttribute('css selector', '#main ul li a.first', 'href', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getAttribute({\n *       selector: '#main ul li a.first',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     }, 'href', function(result) {\n *       console.log('result', result);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getAttribute('#main ul li a.first', 'href');\n *     console.log('attribute', result);\n *   }\n * }\n *\n * @method getAttribute\n * @syntax .getAttribute(selector, attribute, callback)\n * @syntax .getAttribute(using, selector, attribute, callback)\n * @syntax browser.element(selector).getAttribute(name)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} attribute The attribute name to inspect.\n * @param {function} callback Callback function which is called with the result value; not required if using `await` operator.\n * @returns {*} The value of the attribute\n * @api protocol.elementstate\n * @link /#dfn-get-element-attribute\n */\nclass GetAttribute extends BaseElementCommand {\n  static get namespacedAliases() {\n    return 'getElementAttribute';\n  }\n\n  get extraArgsCount() {\n    return 1;\n  }\n\n  get elementProtocolAction() {\n    return 'getElementAttribute';\n  }\n}\n\nmodule.exports = GetAttribute;\n"
  },
  {
    "path": "lib/api/element-commands/getCssProperty.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Retrieve the value of a css property for a given DOM element.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getCssProperty('#main ul li a.first', 'display', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getCssProperty('css selector', '#main ul li a.first', 'display', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getCssProperty({\n *       selector: '#main ul li a.first',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     }, 'display', function(result) {\n *       console.log('result', result);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getCssProperty('#main ul li a.first', 'display');\n *     console.log('display', result);\n *   }\n * }\n *\n * @method getCssProperty\n * @syntax .getCssProperty(selector, cssProperty, callback)\n * @syntax .getCssProperty(using, selector, cssProperty, callback)\n * @syntax browser.element(selector).getCssProperty(name)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} cssProperty The CSS property to inspect.\n * @param {function} callback Callback function which is called with the result value; not required if using `await` operator.\n * @returns {*} The value of the css property\n * @api protocol.elementstate\n * @link /#get-element-css-value\n */\nclass GetCssProperty extends BaseElementCommand {\n  get extraArgsCount() {\n    return 1;\n  }\n\n  get elementProtocolAction() {\n    return 'getElementCSSValue';\n  }\n}\n\nmodule.exports = GetCssProperty;\n"
  },
  {
    "path": "lib/api/element-commands/getElementProperty.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Retrieve the value of a specified DOM property for the given element. For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getElementProperty('#login input[type=text]', 'classList', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getElementProperty('css selector', '#login input[type=text]', 'classList', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getElementProperty({\n *       selector: '#login input[type=text]',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     }, 'classList', function(result) {\n *       console.log('result', result);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getElementProperty('#login input[type=text]', 'classList');\n *     console.log('classList', result);\n *   }\n * }\n *\n * @method getElementProperty\n * @syntax .getElementProperty(selector, property, callback)\n * @syntax .getElementProperty(using, selector, property, callback)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} property The property to inspect.\n * @param {function} callback Callback function which is called with the result value; not required if using `await` operator.\n * @returns {*} The value of the property\n * @api protocol.elementstate\n * @link /#get-element-property\n */\nclass GetElementProperty extends BaseElementCommand {\n  get extraArgsCount() {\n    return 1;\n  }\n\n  get elementProtocolAction() {\n    return 'getElementProperty';\n  }\n}\n\nmodule.exports = GetElementProperty;\n"
  },
  {
    "path": "lib/api/element-commands/getElementRect.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Determine an element's size in pixels. For W3C Webdriver compatible clients (such as GeckoDriver), this command is equivalent to `getLocation` and both return\n * the dimensions and coordinates of the given element:\n * - x: X axis position of the top-left corner of the element, in CSS pixels\n * - y: Y axis position of the top-left corner of the element, in CSS pixels\n * - height: Height of the element’s bounding rectangle in CSS pixels;\n * - width: Width of the web element’s bounding rectangle in CSS pixels.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getElementRect('#login', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getElementRect('css selector', '#login', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getElementRect({\n *       selector: '#login',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     }, function(result) {\n *       console.log('result', result);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getElementRect('#login');\n *     console.log('classList', result);\n *   }\n * }\n *\n * @method getElementRect\n * @syntax .getElementRect(selector, callback)\n * @syntax .getElementRect(using, selector, callback)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @returns {{width: number, height: number}} The width and height of the element in pixels\n * @link /#dfn-get-element-rect\n * @api protocol.elementstate\n */\nclass GetElementRect extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'getElementRect';\n  }\n}\n\nmodule.exports = GetElementRect;\n"
  },
  {
    "path": "lib/api/element-commands/getElementSize.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Determine an element's size in pixels. For W3C Webdriver compatible clients (such as GeckoDriver), this command is equivalent to `getLocation` and both return\n * the dimensions and coordinates of the given element:\n * - x: X axis position of the top-left corner of the element, in CSS pixels\n * - y: Y axis position of the top-left corner of the element, in CSS pixels\n * - height: Height of the element’s bounding rectangle in CSS pixels;\n * - width: Width of the web element’s bounding rectangle in CSS pixels.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getElementSize('#login', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getElementSize('css selector', '#login', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getElementSize({\n *       selector: '#login',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     }, function(result) {\n *       console.log('result', result);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getElementSize('#login');\n *     console.log('classList', result);\n *   }\n * }\n *\n * @method getElementSize\n * @syntax .getElementSize(selector, callback)\n * @syntax .getElementSize(using, selector, callback)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @returns {{width: number, height: number}} The width and height of the element in pixels\n * @link /#dfn-get-element-rect\n * @api protocol.elementstate\n */\nclass GetElementSize extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'getElementRect';\n  }\n}\n\nmodule.exports = GetElementSize;\n"
  },
  {
    "path": "lib/api/element-commands/getFirstElementChild.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n/**\n * Returns an element's first child. The child element will be returned as web element JSON object (with an added .getId() convenience method).\n *\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     const resultElement = await browser.getFirstElementChild('.features-container');\n *\n *     console.log('last child element Id:', resultElement.getId());\n *   },\n *\n * @syntax browser.getFirstElementChild(selector, callback)\n * @syntax browser.getFirstElementChild(selector)\n * @syntax browser.element(selector).getFirstElementChild()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @method getFirstElementChild\n * @since 2.0.0\n * @moreinfo developer.mozilla.org/en-US/docs/Web/API/Element/firstElementChild\n * @api protocol.elements\n */\nclass GetFirstElementChild extends BaseElementCommand {\n\n  get extraArgsCount() {\n    return 0;\n  }\n\n  async protocolAction() {\n    const result = await this.executeProtocolAction('getFirstElementChild');\n\n    return result;\n  }\n}\n\nmodule.exports = GetFirstElementChild;\n"
  },
  {
    "path": "lib/api/element-commands/getLastElementChild.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Returns an element's last child. The child element will be returned as web element JSON object (with an added .getId() convenience method).\n *\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     const resultElement = await browser.getLastElementChild('.features-container');\n *\n *     console.log('last child element Id:', resultElement.getId());\n *   },\n *\n * @syntax browser.getLastElementChild(selector, callback)\n * @syntax browser.getLastElementChild(selector)\n * @syntax browser.element(selector).getLastElementChild()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @method getLastElementChild\n * @since 2.0.0\n * @moreinfo developer.mozilla.org/en-US/docs/Web/API/Element/lastElementChild\n * @api protocol.elements\n */\nclass GetLastElementChild extends BaseElementCommand {\n\n  get extraArgsCount() {\n    return 0;\n  }\n\n  async protocolAction() {\n    return this.executeProtocolAction('getLastElementChild');\n  }\n}\n\nmodule.exports = GetLastElementChild;\n"
  },
  {
    "path": "lib/api/element-commands/getLocation.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Determine an element's location on the page. The point (0, 0) refers to the upper-left corner of the page. The element's coordinates are returned as a JSON object with x and y properties.\n *\n * For W3C Webdriver compatible clients (such as GeckoDriver), this command is equivalent to `getElementSize` and both return\n * the dimensions and coordinates of the given element:\n * - x: X axis position of the top-left corner of the element, in CSS pixels\n * - y: Y axis position of the top-left corner of the element, in CSS pixels\n * - height: Height of the element’s bounding rectangle in CSS pixels;\n * - width: Width of the web element’s bounding rectangle in CSS pixels.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getLocation('#login', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getLocation('css selector', '#login', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getLocation({\n *       selector: '#login',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     }, function(result) {\n *       console.log('result', result);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getLocation('#login');\n *     console.log('location', result);\n *   }\n * }\n *\n * @method getLocation\n * @syntax .getLocation(selector, callback)\n * @syntax .getLocation(using, selector, callback)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @returns {{x:number, y:number}} The X and Y coordinates for the element on the page.\n * @link /#dfn-get-element-rect\n * @api protocol.elementlocation\n */\nclass GetLocation extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'getElementRect';\n  }\n}\n\nmodule.exports = GetLocation;\n"
  },
  {
    "path": "lib/api/element-commands/getLocationInView.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Determine an element's location on the screen once it has been scrolled into view.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.getLocationInView(\"#main ul li a.first\", function(result) {\n *     this.assert.equal(typeof result, \"object\");\n *     this.assert.equal(result.status, 0);\n *     this.assert.equal(result.value.x, 200);\n *     this.assert.equal(result.value.y, 200);\n *   });\n * };\n *\n *\n * @method getLocationInView\n * @syntax .getLocationInView(selector, callback)\n * @syntax .getLocationInView(using, selector, callback)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @returns {{x: number, y: number}} The X and Y coordinates for the element on the page.\n * @jsonwire\n * @api protocol.elementlocation\n * @deprecated This is a JSON Wire Protocol command and is no longer supported.\n */\nclass GetLocationInView extends BaseElementCommand {\n  get w3c_deprecated() {\n    return true;\n  }\n\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'isElementLocationInView';\n  }\n}\n\nmodule.exports = GetLocationInView;\n"
  },
  {
    "path": "lib/api/element-commands/getNextSibling.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n/**\n * Returns the element immediately following the specified one in their parent's childNodes. The element will be returned as web element JSON object (with an added .getId() convenience method).\n *\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     const resultElement = await browser.getNextSibling('.features-container li:first-child');\n *\n *     console.log('next sibling element Id:', resultElement.getId());\n *   },\n *\n * @syntax browser.getNextSibling(selector, callback)\n * @syntax browser.getNextSibling(selector)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @method getNextSibling\n * @moreinfo developer.mozilla.org/en-US/docs/Web/API/Element/nextElementSibling\n * @since 2.0.0\n * @api protocol.elements\n * @exampleLink /api/getNextSibling.js\n */\nclass GetNextSibling extends BaseElementCommand {\n\n  get extraArgsCount() {\n    return 0;\n  }\n\n  async protocolAction() {\n    return await this.executeProtocolAction('getNextSibling');\n  }\n}\n\nmodule.exports = GetNextSibling;\n"
  },
  {
    "path": "lib/api/element-commands/getPreviousSibling.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n/**\n *  Returns the element immediately preceding the specified one in its parent's child elements list. The element will be returned as web element JSON object (with an added `.getId()` convenience method).\n *\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     const resultElement = await browser.getPreviousSibling('.features-container li:second-child');\n *\n *     console.log('previous sibling element Id:', resultElement.getId());\n *   },\n *\n * @syntax browser.getPreviousSibling('#web-button', function(result) {\n *\n *   console.log(result.value)\n * }})\n * await browser.getPreviousSibling('#web-button')\n * await browser.getPreviousSibling({selector: '#web-button', locateStrategy: 'css selector'})\n *\n * @syntax\n * // with global element():\n * const formEl = element('form');\n * const result = await browser.getPreviousSibling(formEl)\n *\n * @syntax\n * // with Selenium By() locators\n * // https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_By.html\n * const locator = by.tagName('form');\n * const result = await browser.getPreviousSibling(locator)\n *\n * @syntax\n * // with browser.findElement()\n * const formEl = await browser.findElement('form');\n * const result = await browser.getPreviousSibling(formEl)\n *\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @method getPreviousSibling\n * @returns {object} The resolved element object, which contains a convenience `.getId()` method that can be used to retrieve the element ID\n * @since 2.0.0\n * @moreinfo developer.mozilla.org/en-US/docs/Web/API/Element/previousElementSibling\n * @api protocol.elements\n */\nclass GetPreviousSibling extends BaseElementCommand {\n\n  get extraArgsCount() {\n    return 0;\n  }\n\n  async protocolAction() {\n    return this.executeProtocolAction('getPreviousSibling');\n  }\n}\n\nmodule.exports = GetPreviousSibling;\n"
  },
  {
    "path": "lib/api/element-commands/getShadowRoot.js",
    "content": "const {ShadowRoot} = require('selenium-webdriver/lib/webdriver');\nconst {WEB_ELEMENT_ID} = require('../../transport/selenium-webdriver/session.js');\nconst BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Returns the `shadowRoot` read-only property which represents the shadow root hosted by the element. This can further be used to retrieve elements part of the shadow root element.\n *\n * @example\n * describe('Shadow Root example test', function() {\n *   it('retrieve the shadowRoot', async function(browser) {\n *      await browser\n *        .navigateTo('https://mdn.github.io/web-components-examples/popup-info-box-web-component/')\n *        .waitForElementVisible('form');\n *\n *      const shadowRootEl = await browser.getShadowRoot('popup-info');\n *      const infoElement = await shadowRootEl.find('.info');\n *\n *      await expect(infoElement.property('innerHTML')).to.include('card validation code');\n *      const iconElement = await shadowRootEl.find('.icon');\n *      const firstElement = await browser.getFirstElementChild(iconElement);\n *\n *      await expect.element(firstElement).to.be.an('img');\n *    });\n * });\n *\n * @syntax browser.getShadowRoot(selector, callback)\n * @syntax browser.getShadowRoot(selector)\n * @syntax browser.element(selector).getShadowRoot()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object|WebElement|By} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @method getShadowRoot\n * @since 2.0.0\n * @moreinfo developer.mozilla.org/en-US/docs/Web/API/Element/shadowRoot\n * @api protocol.elements\n */\nclass ElementCommand extends BaseElementCommand {\n  async protocolAction() {\n    const result = await this.executeProtocolAction('getShadowRoot');\n\n    if (result instanceof ShadowRoot) {\n      // treat the ShadowRoot as WebElement, so that the WebElement\n      // methods continue to be available on shadow root.\n      return this.api.createElement({[WEB_ELEMENT_ID]: result.getId()});\n    }\n\n    return result;\n  }\n}\n\nmodule.exports = ElementCommand;\n\n"
  },
  {
    "path": "lib/api/element-commands/getTagName.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Query for an element's tag name.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getTagName('#login', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getTagName('css selector', '#login', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getTagName({\n *       selector: '#login',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     }, function(result) {\n *       console.log('result', result);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getTagName('#login');\n *     console.log('tagName', result);\n *   }\n * }\n *\n * @method getTagName\n * @syntax .getTagName(selector, callback)\n * @syntax .getTagName(using, selector, callback)\n * @syntax browser.element(selector).getTagName()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @returns {number} The element's tag name, as a lowercase string.\n * @link /#dfn-get-element-tag-name\n * @api protocol.elementstate\n */\nclass GetTagName extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'getElementTagName';\n  }\n}\n\nmodule.exports = GetTagName;\n"
  },
  {
    "path": "lib/api/element-commands/getText.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Returns the visible text for the element.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getText('#main ul li a.first', function(result) {\n *       this.assert.equal(typeof result, 'object);\n *       this.assert.strictEqual(result.status, 0); // only when using Selenium / JSONWire\n *       this.assert.equal(result.value, 'nightwatchjs.org');\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getText('css selector', '#main ul li a.first', function(result) {\n *       console.log('getText result', result.value);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getText({\n *       selector: '#main ul li a',\n *       index: 1\n *     }, function(result) {\n *       console.log('getText result', result.value);\n *     });\n *\n *     browser.getText({\n *       selector: '#main ul li a.first',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     }, function(result) {\n *       console.log('getText result', result.value);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getText('#main ul li a.first');\n *     console.log('getText result', result);\n *   }\n * }\n *\n * @method getText\n * @syntax .getText(selector, callback)\n * @syntax .getText(using, selector, callback)\n * @syntax browser.element(selector).getText()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string} selector The CSS/Xpath selector used to locate the element.\n * @param {function} callback Callback function which is called with the result value.\n * @returns {string} The element's visible text.\n * @link /#dfn-get-element-text\n * @api protocol.elementstate\n */\nclass GetText extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'getElementText';\n  }\n}\n\nmodule.exports = GetText;\n"
  },
  {
    "path": "lib/api/element-commands/getValue.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Returns a form element current value.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.getValue('#login input[type=text]', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.getValue('css selector', '#login input[type=text]', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.getValue({\n *       selector: '#login input[type=text]',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     }, function(result) {\n *       console.log('result', result);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.getValue('#login input[type=text]');\n *     console.log('Value', result);\n *   }\n * }\n *\n * @method getValue\n * @syntax .getValue(selector, callback)\n * @syntax browser.element(selector).getValue()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @returns {string} The element's value.\n * @link /#get-element-property\n * @api protocol.elementstate\n */\nclass GetValue extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  protocolAction() {\n    return this.executeProtocolAction('getElementProperty', ['value']);\n  }\n}\n\nmodule.exports = GetValue;\n"
  },
  {
    "path": "lib/api/element-commands/hasDescendants.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n/**\n * Returns true or false based on whether the DOM has any child nodes\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     const result = await browser.hasDescendants('.features-container');\n *\n *     console.log('true or false:', result);\n *   },\n *\n * @syntax browser.hasDescendants(selector, callback)\n * @syntax browser.hasDescendants(selector)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @method hasDescendants\n * @api protocol.elementstate\n * @since 2.0.0\n * @moreinfo developer.mozilla.org/en-US/docs/Web/API/Element/childElementCount\n */\nclass HasDescendants extends BaseElementCommand {\n\n  async protocolAction() {\n    return await this.executeProtocolAction('elementHasDescendants');\n  }\n\n}\n\nmodule.exports = HasDescendants;\n\n"
  },
  {
    "path": "lib/api/element-commands/isEnabled.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Determines if an element is enabled, as indicated by the 'disabled' attribute.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.isEnabled('#main select option.first', function(result) {\n *       this.assert.equal(typeof result, \"object\");\n *       this.assert.equal(result.status, 0);\n *       this.assert.equal(result.value, true);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.isEnabled('css selector', '#main select option.first');\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.isEnabled({\n *       selector: '#main ul li a',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     });\n *\n *     browser.isEnabled({\n *       selector: '#main select option.first',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.isEnabled('#main select option.first');\n *     console.log('isVisible result', result);\n *   }\n * }\n *\n * @method isEnabled\n * @syntax .isEnabled(selector, callback)\n * @syntax .isEnabled(using, selector, callback)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @link /#is-element-enabled\n * @api protocol.elementstate\n */\nclass IsEnabled extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'isElementEnabled';\n  }\n\n}\n\nmodule.exports = IsEnabled;\n"
  },
  {
    "path": "lib/api/element-commands/isPresent.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\nconst {Logger, filterStackTrace} = require('../../utils');\n/**\n * Determines if an element is present in the DOM.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.isPresent('#main ul li a.first', function(result) {\n *       this.assert.equal(typeof result, \"object\");\n *       this.assert.equal(result.status, 0);\n *       this.assert.equal(result.value, true);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.isPresent('css selector', '#main ul li a.first');\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.isPresent({\n *       selector: '#main ul li a',\n *       index: 1,\n *     });\n *\n *     browser.isPresent({\n *       selector: '#main ul li a.first',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.isPresent('#main ul li a.first');\n *     console.log('isPresent result', result);\n *   }\n * }\n *\n * @method isPresent\n * @syntax .isPresent(selector, callback)\n * @syntax .isPresent(using, selector, callback)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementstate\n */\nclass isPresent extends BaseElementCommand {\n  elementLocateError(error) {\n    if (error.response) {\n      error.detailedErr  = JSON.stringify(error.response);\n    }\n    error.stack = filterStackTrace(this.stackTrace);\n    Logger.error(error);\n\n    return this.complete(null, {\n      status: 0,\n      value: false\n    });\n  }\n\n  async protocolAction() {\n    const result = {\n      status: 0,\n      value: false\n    };\n\n    if (this.webElement || this.elementId) {\n      result.value = true;\n    }\n\n    return result;\n  }\n\n}\n\nmodule.exports = isPresent;\n"
  },
  {
    "path": "lib/api/element-commands/isSelected.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Determines if an element is selected.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.isSelected('#main select option.first', function(result) {\n *       this.assert.equal(typeof result, \"object\");\n *       this.assert.equal(result.status, 0);\n *       this.assert.equal(result.value, true);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.isSelected('css selector', '#main select option.first');\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.isSelected({\n *       selector: '#main ul li a',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     });\n *\n *     browser.isSelected({\n *       selector: '#main select option.first',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.isSelected('#main select option.first');\n *     console.log('isVisible result', result);\n *   }\n * }\n *\n * @method isSelected\n * @syntax .isSelected(selector, callback)\n * @syntax .isSelected(using, selector, callback)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @link /#is-element-selected\n * @api protocol.elementstate\n */\nclass IsSelected extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'isElementSelected';\n  }\n\n}\n\nmodule.exports = IsSelected;\n"
  },
  {
    "path": "lib/api/element-commands/isVisible.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\nconst {isUndefined} = require('../../utils');\n\n/**\n * Determine if an element is currently displayed.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.isVisible('#main ul li a.first', function(result) {\n *       this.assert.equal(typeof result, \"object\");\n *       this.assert.equal(result.status, 0);\n *       this.assert.equal(result.value, true);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.isVisible('css selector', '#main ul li a.first');\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.isVisible({\n *       selector: '#main ul li a',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     });\n *\n *     browser.isVisible({\n *       selector: '#main ul li a.first',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.isVisible('#main ul li a.first');\n *     console.log('isVisible result', result);\n *   }\n * }\n *\n * @method isVisible\n * @syntax .isVisible(selector, callback)\n * @syntax .isVisible(using, selector, callback)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} callback Callback function which is called with the result value.\n * @link /#element-displayedness\n * @api protocol.elementstate\n */\nclass IsVisible extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  protocolAction() {\n    return this.executeProtocolAction('isElementDisplayed');\n  }\n}\n\nmodule.exports = IsVisible;\n"
  },
  {
    "path": "lib/api/element-commands/moveToElement.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Move the mouse by an offset of the specified element. If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.moveToElement('#main', 10, 10);\n * };\n *\n *\n * @method moveToElement\n * @syntax .moveToElement(selector, xoffset, yoffset, [callback])\n * @syntax .moveToElement(using, selector, xoffset, yoffset, [callback])\n * @syntax browser.element(selector).moveTo([x], [y])\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {number} xoffset X offset to move to, relative to the center of the element.\n * @param {number} yoffset Y offset to move to, relative to the center of the element.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @jsonwire\n * @api protocol.elementinteraction\n */\nclass MoveToElement extends BaseElementCommand {\n  get extraArgsCount() {\n    return 2;\n  }\n\n  get elementProtocolAction() {\n    return 'moveTo';\n  }\n}\n\nmodule.exports = MoveToElement;\n"
  },
  {
    "path": "lib/api/element-commands/rightClick.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Simulates a context-click(right click) event on the given DOM element. The element is scrolled into view if it is not already pointer-interactable. See the WebDriver specification for element [interactability](https://www.w3.org/TR/webdriver/#element-interactability).\n *\n * @example\n * module.exports = {\n *   demoTest() {\n *     browser.rightClick('#main ul li a.first');\n *\n *     browser.rightClick('#main ul li a.first', function(result) {\n *       console.log('Click result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.rightClick('css selector', '#main ul li a.first');\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.rightClick({\n *       selector: '#main ul li a',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     });\n *\n *     browser.rightClick({\n *       selector: '#main ul li a.first',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   },\n *\n *   demoTestAsync: async function() {\n *     const result = await browser.rightClick('#main ul li a.first');\n *     console.log('Right click result', result);\n *   }\n * }\n *\n * @method rightClick\n * @syntax .rightClick(selector, [callback])\n * @syntax .rightClick(using, selector, [callback])\n * @syntax browser.element(selector).rightClick()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string} selector The CSS/Xpath selector used to locate the element.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinteraction\n * @since 2.0.0\n * @see https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#context-click\n */\nclass RightClick extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'contextClick';\n  }\n}\n\nmodule.exports = RightClick;\n"
  },
  {
    "path": "lib/api/element-commands/sendKeys.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Types a key sequence on the DOM element. Can be used to send a sequence of key strokes to an element. Any UTF-8 character may be specified.\n *\n *\n * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), is loaded onto the main Nightwatch instance as `browser.Keys`.\n *\n * @example\n * // send some simple text to an input\n * this.demoTest = function (browser) {\n *   browser.sendKeys('input[type=text]', 'nightwatch');\n * };\n * //\n * // send some text to an input and hit enter.\n * this.demoTest = function (browser) {\n *   browser.sendKeys('input[type=text]', ['nightwatch', browser.Keys.ENTER]);\n * };\n *\n *\n * @link /session/:sessionId/element/:id/value\n * @method sendKeys\n * @syntax .sendKeys(selector, inputValue, [callback])\n * @syntax browser.element(selector).sendKeys(...keys)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string|array} inputValue The text to send to the element or key strokes.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @link https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#sendKeys\n * @api protocol.elementinteraction\n */\nclass SendKeys extends BaseElementCommand {\n  static get isTraceable() {\n    return true;\n  }\n\n  get extraArgsCount() {\n    return 1;\n  }\n\n  get elementProtocolAction() {\n    return 'sendKeysToElement';\n  }\n}\n\nmodule.exports = SendKeys;\n"
  },
  {
    "path": "lib/api/element-commands/setAttribute.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Set the value of a specified DOM attribute for the given element. For all the available DOM attributes, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.setAttribute('#login input[type=text]', 'disabled', 'true', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.setAttribute('css selector', '#login input[type=text]', 'disabled', 'true', function(result) {\n *       console.log('result', result);\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.setAttribute({\n *       selector: '#login input[type=text]',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     }, 'disabled', 'true', function(result) {\n *       console.log('result', result);\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     await browser.setAttribute('#login input[type=text]', 'disabled', 'true');\n *   }\n * }\n *\n * @method setAttribute\n * @syntax .setAttribute(selector, attribute, value, [callback])\n * @syntax .setAttribute(using, selector, attribute, value, [callback])\n * @syntax browser.element(selector).setAttribute(name, value)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string} attribute The attribute name to set.\n * @param {string} value The attribute value name to set.\n * @param {function} callback Callback function which is called with the result value; not required if using `await` operator.\n * @api protocol.elementinteraction\n */\nclass SetAttribute extends BaseElementCommand {\n  get extraArgsCount() {\n    return 2;\n  }\n\n  get elementProtocolAction() {\n    return 'setElementAttribute';\n  }\n}\n\nmodule.exports = SetAttribute;\n"
  },
  {
    "path": "lib/api/element-commands/setPassword.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * An alias of \"setValue\" command, but hides the content from the nightwatch logs.\n *\n * <div class=\"alert alert-warning\"><strong>setValue/setPassword</strong> also clears the existing value of the element by calling the <strong>clear()</strong> command beforehand.</div>\n *\n * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), is loaded onto the main Nightwatch instance as `browser.Keys`.\n *\n * @example\n * // send some simple text to an input\n * this.demoTest = function (browser) {\n *   browser.setPassword('input[type=text]', 'nightwatch');\n * };\n *\n * // send some text to an input and hit enter.\n * this.demoTest = function (browser) {\n *   browser.setPassword('input[type=text]', ['nightwatch', browser.Keys.ENTER]);\n * };\n *\n * @method setPassword\n * @syntax .setPassword(selector, inputValue, [callback])\n * @syntax .setPassword(using, selector, inputValue, [callback])\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string|array} inputValue The text to send to the element or key strokes.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @link /#element-send-keys\n * @api protocol.elementinteraction\n */\nclass SetPassword extends BaseElementCommand {\n  static get namespacedAliases() {\n    return 'sendKeysRedacted';\n  }\n\n  static get RedactParams(){\n    return true;\n  }\n\n  get extraArgsCount() {\n    return 1;\n  }\n\n  get elementProtocolAction() {\n    return 'setElementValueRedacted';\n  }\n}\n\nmodule.exports = SetPassword;\n"
  },
  {
    "path": "lib/api/element-commands/setValue.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Sends some text to an element. Can be used to set the value of a form element or to send a sequence of key strokes to an element. Any UTF-8 character may be specified.\n *\n * <div class=\"alert alert-warning\">From Nightwatch v2, <strong>setValue</strong> also clears the existing value of the element by calling the <strong>clearValue()</strong> beforehand.</div>\n *\n * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), is loaded onto the main Nightwatch instance as `browser.Keys`.\n *\n * @example\n * // send some simple text to an input\n * this.demoTest = function (browser) {\n *   browser.setValue('input[type=text]', 'nightwatch');\n * };\n *\n * // send some text to an input and hit enter.\n * this.demoTest = function (browser) {\n *   browser.setValue('input[type=text]', ['nightwatch', browser.Keys.ENTER]);\n * };\n *\n *\n * @link /session/:sessionId/element/:id/value\n * @method setValue\n * @syntax .setValue(selector, inputValue, [callback])\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string|array} inputValue The text to send to the element or key strokes.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @link /#element-send-keys\n * @api protocol.elementinteraction\n */\nclass SetValue extends BaseElementCommand {\n\n  static get isTraceable() {\n    return true;\n  }\n\n  get extraArgsCount() {\n    return 1;\n  }\n\n  get elementProtocolAction() {\n    return 'setElementValue';\n  }\n}\n\nmodule.exports = SetValue;\n"
  },
  {
    "path": "lib/api/element-commands/submitForm.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Submits the form containing this element (or this element if it is itself a FORM element). his command is a no-op if the element is not contained in a form.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.submitForm('form.login');\n * };\n *\n *\n * @method submitForm\n * @syntax .submitForm(selector, [callback])\n * @syntax .submitForm(using, selector, [callback])\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @jsonwire\n * @api protocol.elementinteraction\n */\nclass SubmitForm extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'elementSubmit';\n  }\n}\n\nmodule.exports = SubmitForm;\n"
  },
  {
    "path": "lib/api/element-commands/takeElementScreenshot.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Take a screenshot of the visible region encompassed by this element's bounding rectangle.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.takeElementScreenshot('#main', function (imageData, err) {\n *       require('fs').writeFile('out.png', imageData.value, 'base64', function (err) {\n *         console.log(err);\n *       });\n *     });\n *\n *     // with explicit locate strategy\n *     browser.takeElementScreenshot('css selector', '#main', function(imageData, err) {\n *       require('fs').writeFile('out.png', imageData.value, 'base64', function (err) {\n *         console.log(err);\n *       });\n *     });\n *\n *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n *     browser.takeElementScreenshot({\n *       selector: '#main ul li a',\n *       index: 1\n *     }, function(imageData, err) {\n *       require('fs').writeFile('out.png', imageData.value, 'base64', function (err) {\n *         console.log(err);\n *       });\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const data = await browser.takeElementScreenshot('#main');\n *     require('fs').writeFile('out.png', data, 'base64');\n *   }\n * }\n *\n * @method takeElementScreenshot\n * @syntax .takeElementScreenshot(selector, callback)\n * @syntax .takeElementScreenshot(using, selector, callback)\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string} selector The CSS/Xpath selector used to locate the element.\n * @param {function} callback Callback function which is called with the result value.\n * @returns {string} Take a screenshot of the visible region encompassed by this element's bounding rectangle.\n * @link /#dfn-take-element-screenshot\n * @api protocol.screens\n * @since 2.0.0\n */\nclass TakeElementScreenshot extends BaseElementCommand {\n  get elementProtocolAction() {\n    return 'takeElementScreenshot';\n  }\n}\n\nmodule.exports = TakeElementScreenshot;\n"
  },
  {
    "path": "lib/api/element-commands/uncheck.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Will uncheck, by clicking, on a checkbox or radio input if it is not already unchecked.\n *\n * @example\n * module.exports = {\n *   demoTest(browser) {\n *     browser.uncheck('input[type=checkbox]:checked)');\n *\n *     browser.uncheck('input[type=checkbox]:checked)', function(result) {\n *       console.log('Check result', result);\n *     });\n *\n *     // with explicit locate strategy\n *     browser.uncheck('css selector', 'input[type=checkbox]:checked)');\n *\n *     // with selector object - see https://nightwatchjs.org/guide#element-properties\n *     browser.uncheck({\n *       selector: 'input[type=checkbox]:checked)',\n *       index: 1,\n *       suppressNotFoundErrors: true\n *     });\n *\n *     browser.uncheck({\n *       selector: 'input[type=checkbox]:checked)',\n *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n *     });\n *   },\n *\n *   demoTestAsync: async function(browser) {\n *     const result = await browser.uncheck('input[type=checkbox]:checked)');\n *     console.log('Check result', result);\n *   }\n * }\n *\n * @method check\n * @syntax .uncheck(selector, [callback])\n * @syntax .uncheck(using, selector, [callback])\n * @syntax browser.element(selector).uncheck()\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string} selector The CSS/Xpath selector used to locate the element.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinteraction\n */\nclass UncheckElement extends BaseElementCommand {\n  get extraArgsCount() {\n    return 0;\n  }\n\n  get elementProtocolAction() {\n    return 'uncheckElement';\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  async protocolAction() {\n    return this.executeProtocolAction(this.elementProtocolAction);\n  }\n}\n\nmodule.exports = UncheckElement;\n"
  },
  {
    "path": "lib/api/element-commands/updateValue.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Sends some text to an element. Can be used to set the value of a form element or to send a sequence of key strokes to an element. Any UTF-8 character may be specified.\n *\n * <div class=\"alert alert-warning\"><strong>updateValue</strong> is equivalent with <strong>setValue</strong> in that it also clears the value beforehand.</div>\n *\n * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), is loaded onto the main Nightwatch instance as `browser.Keys`.\n *\n * @example\n * // send some simple text to an input\n * this.demoTest = function (browser) {\n *   browser.updateValue('input[type=text]', 'nightwatch');\n * };\n *\n * // send some text to an input and hit enter.\n * this.demoTest = function (browser) {\n *   browser.updateValue('input[type=text]', ['nightwatch', browser.Keys.ENTER]);\n * };\n *\n *\n * @link /session/:sessionId/element/:id/value\n * @method updateValue\n * @syntax .updateValue(selector, inputValue, [callback])\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string|array} inputValue The text to send to the element or key strokes.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @link /#element-send-keys\n * @api protocol.elementinteraction\n */\nclass SetValue extends BaseElementCommand {\n  get extraArgsCount() {\n    return 1;\n  }\n\n  get elementProtocolAction() {\n    return 'setElementValue';\n  }\n\n  protocolAction() {\n    return this.executeProtocolAction('clearElementValue', this.args).then(_ => {\n      return this.executeProtocolAction('setElementValue', this.args);\n    });\n  }\n}\n\nmodule.exports = SetValue;\n"
  },
  {
    "path": "lib/api/element-commands/uploadFile.js",
    "content": "const BaseElementCommand = require('./_baseElementCommand.js');\n\n/**\n * Uploads file to an element using absolute file path.\n *\n * @example\n * // send a file to for upload to a field.\n * this.demoTest = function (browser) {\n *   browser.uploadFile('#myFile', '/path/file.pdf');\n * };\n * //\n *\n * @method uploadFile\n * @syntax .uploadFile(selector, absoluteFilePath, [callback])\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {string|array} inputValue The file path to upload.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @moreinfo www.selenium.dev/documentation/en/remote_webdriver/remote_webdriver_client/\n * @api protocol.elementinteraction\n * @since 2.0.0\n */\n\nclass UploadFile extends BaseElementCommand {\n  get extraArgsCount() {\n    return 1;\n  }\n\n  get elementProtocolAction() {\n    return 'uploadFile';\n  }\n}\n\n\nmodule.exports = UploadFile;\n"
  },
  {
    "path": "lib/api/element-commands/waitForElementNotPresent.js",
    "content": "const WaitForElement = require('./_waitFor.js');\n\n/**\n * Opposite of `waitForElementPresent`. Waits a given time in milliseconds (default 5000ms) for an element to be not present (i.e. removed) in the page before performing any other commands or assertions.\n * If the element is still present after the specified amount of time, the test fails.\n *\n * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file.\n * Similarly, a default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds).\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     // with default implicit timeout of 5000ms (can be overwritten in settings under 'globals.waitForConditionTimeout')\n *     browser.waitForElementNotPresent('#dialog');\n *\n *     // specify the locate strategy (css selector/xpath) as the first argument\n *     browser.waitForElementNotPresent('css selector', '#dialog');\n *\n *     // with explicit timeout (in milliseconds)\n *     browser.waitForElementNotPresent('#dialog', 1000);\n *\n *     // continue if failed\n *     browser.waitForElementNotPresent('#dialog', 1000, false);\n *\n *     // with callback\n *     browser.waitForElementNotPresent('#dialog', 1000, function() {\n *       // do something while we're here\n *     });\n *\n *     // with custom output message - the locate strategy is required\n *     browser.waitForElementNotPresent('css selector', '#dialog', 'The dialog container is removed.');\n *\n *     // with custom Spanish message\n *     browser.waitForElementNotPresent('#dialog', 1000, 'elemento %s no era presente en %d ms');\n *\n *     // many combinations possible - the message is always the last argument\n *     browser.waitForElementNotPresent('#dialog', 1000, false, function() {}, 'elemento %s no era presente en %d ms');\n *   },\n *\n *   'demo Test with selector objects': function(browser) {\n *      browser.waitForElementNotPresent({\n *        selector: '#dialog',\n *        timeout: 1000\n *      });\n *\n *      browser.waitForElementNotPresent({\n *        selector: '#dialog',\n *        locateStrategy: 'css selector'\n *      }, 'Custom output message');\n *\n *      browser.waitForElementNotPresent({\n *        selector: '.container',\n *        index: 2,\n *        retryInterval: 100,\n *        abortOnFailure: true\n *      });\n *   }\n *\n *   'page object demo Test': function (browser) {\n *      var nightwatch = browser.page.nightwatch();\n *      nightwatch\n *        .navigate()\n *        .assert.titleContains('Nightwatch.js');\n *\n *      nightwatch..waitForElementNotPresent('@dialogContainer', function(result) {\n *        console.log(result);\n *      });\n *   }\n * }\n *\n * @syntax .waitForElementNotPresent([using], selector, [timeout], [pollInterval], [abortOnAssertionFailure], [callback], [message]);\n * @method waitForElementNotPresent\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {number} [time=waitForConditionTimeout] The total number of milliseconds to wait before failing.\n * @param {number} [poll=waitForConditionPollInterval] The number of milliseconds to wait between checks. You can use this only if you also specify the time parameter.\n * @param {boolean} [abortOnFailure=abortOnAssertionFailure] By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. To set this globally you can define a property `abortOnAssertionFailure` in your globals.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @param {string} [message] Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time (e.g. Element %s was not in the page for %d ms).\n * @see waitForElementPresent\n * @sortIndex 10\n * @api protocol.waitforelements\n */\nclass WaitForElementNotPresent extends WaitForElement {\n  get retryOnSuccess() {\n    return true;\n  }\n\n  constructor(opts) {\n    super(opts);\n\n    this.expectedValue = 'not found';\n  }\n\n  /**\n   * Overriding elementFound to fail the test\n   *\n   * @param result\n   * @returns {Promise}\n   */\n  elementFound(result) {\n    const defaultMsg = 'Timed out while waiting for element <%s> to be removed for %d milliseconds.';\n    result.passed = false;\n\n    return this.fail(result, 'found', this.expectedValue, defaultMsg);\n  }\n\n  elementNotFound(result) {\n    const defaultMsg = 'Element <%s> was not present after %d milliseconds.';\n    result.passed = true;\n\n    return this.pass(result, defaultMsg, this.executor.elapsedTime);\n  }\n}\n\nmodule.exports = WaitForElementNotPresent;\n"
  },
  {
    "path": "lib/api/element-commands/waitForElementNotVisible.js",
    "content": "const WaitForDisplayed = require('./_waitForDisplayed.js');\n\n/**\n * Opposite of `waitForElementVisible`. Waits a given time in milliseconds (default 5000ms) for an element to be not visible (i.e. hidden but existing) in the page before performing any other commands or assertions.\n * If the element fails to be hidden in the specified amount of time, the test fails.\n *\n * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file.\n * Similarly, a default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds).\n *\n @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     // with default implicit timeout of 5000ms (can be overwritten in settings under 'globals.waitForConditionTimeout')\n *     browser.waitForElementNotVisible('#dialog');\n *\n *     // specify the locate strategy (css selector/xpath) as the first argument\n *     browser.waitForElementNotVisible('css selector', '#dialog');\n *\n *     // with explicit timeout (in milliseconds)\n *     browser.waitForElementNotVisible('#dialog', 1000);\n *\n *     // continue if failed\n *     browser.waitForElementNotVisible('#dialog', 1000, false);\n *\n *     // with callback\n *     browser.waitForElementNotVisible('#dialog', 1000, function() {\n *       // do something while we're here\n *     });\n *\n *     // with custom output message - the locate strategy is required\n *     browser.waitForElementNotVisible('css selector', '#dialog', 'The dialog container is not visible.');\n *\n *     // with custom Spanish message\n *     browser.waitForElementNotVisible('#dialog', 1000, 'elemento %s no era visible en %d ms');\n *\n *     // many combinations possible - the message is always the last argument\n *     browser.waitForElementNotVisible('#dialog', 1000, false, function() {}, 'elemento %s no era visible en %d ms');\n *   },\n *\n *   'demo Test with selector objects': function(browser) {\n *      browser.waitForElementNotVisible({\n *        selector: '#dialog',\n *        timeout: 1000\n *      });\n *\n *      browser.waitForElementNotVisible({\n *        selector: '#dialog',\n *        locateStrategy: 'css selector'\n *      }, 'Custom output message');\n *\n *      browser.waitForElementNotVisible({\n *        selector: '.container',\n *        index: 2,\n *        retryInterval: 100,\n *        abortOnFailure: true\n *      });\n *   }\n *\n *   'page object demo Test': function (browser) {\n *      var nightwatch = browser.page.nightwatch();\n *      nightwatch\n *        .navigate()\n *        .assert.titleContains('Nightwatch.js');\n *\n *      nightwatch.waitForElementNotVisible('@mainDialog', function(result) {\n *        console.log(result);\n *      });\n *   }\n * }\n *\n * @syntax .waitForElementNotVisible([using], selector, [timeout], [pollInterval], [abortOnAssertionFailure], [callback], [message]);\n * @method waitForElementNotVisible\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {number} [time=waitForConditionTimeout] The total number of milliseconds to wait before failing.\n * @param {number} [poll=waitForConditionPollInterval] The number of milliseconds to wait between checks. You can use this only if you also specify the time parameter.\n * @param {boolean} [abortOnFailure=abortOnAssertionFailure] By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. To set this globally you can define a property `abortOnAssertionFailure` in your globals.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @param {string} [message] Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time (e.g. Element %s was not in the page for %d ms).\n * @see waitForElementVisible\n * @sortIndex 30\n * @api protocol.waitforelements\n */\nclass WaitForElementNotVisible extends WaitForDisplayed {\n  constructor(opts) {\n    super(opts);\n\n    this.expectedValue = 'not visible';\n  }\n\n  shouldRetryAction(elementVisible) {\n    return elementVisible;\n  }\n\n  elementVisible(response) {\n    const defaultMsg = 'Timed out while waiting for element <%s> to not be visible for %d milliseconds.';\n\n    return this.fail(response, 'visible', this.expectedValue, defaultMsg);\n  }\n\n  elementNotVisible(response) {\n    const defaultMsg = 'Element <%s> was not visible after %d milliseconds.';\n\n    return this.pass(response, defaultMsg, this.executor.elapsedTime);\n  }\n\n}\n\nmodule.exports = WaitForElementNotVisible;\n"
  },
  {
    "path": "lib/api/element-commands/waitForElementPresent.js",
    "content": "const WaitForElement = require('./_waitFor.js');\n\n/**\n * Waits a given time in milliseconds (default 5000ms) for an element to be present in the page before performing any other commands or assertions.\n * If the element fails to be present in the specified amount of time, the test fails. You can change this by setting `abortOnFailure` to `false`.\n *\n * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file.\n * Similarly, the default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds).\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     // with default implicit timeout of 5000ms (can be overwritten in settings under 'globals.waitForConditionTimeout')\n *     browser.waitForElementPresent('#index-container');\n *\n *     // specify the locate strategy (css selector/xpath) as the first argument\n *     browser.waitForElementPresent('css selector', '#index-container');\n *\n *     // with explicit timeout (in milliseconds)\n *     browser.waitForElementPresent('#index-container', 1000);\n *\n *     // continue if failed\n *     browser.waitForElementPresent('#index-container', 1000, false);\n *\n *     // with callback\n *     browser.waitForElementPresent('#index-container', 1000, function() {\n *       // do something while we're here\n *     });\n *\n *     // with custom output message - the locate strategy is required\n *     browser.waitForElementPresent('css selector', '#index-container', 'The index container is found.');\n *\n *     // with custom Spanish message\n *     browser.waitForElementPresent('#index-container', 1000, 'elemento %s no era presente en %d ms');\n *\n *     // many combinations possible - the message is always the last argument\n *     browser.waitForElementPresent('#index-container', 1000, false, function() {}, 'elemento %s no era presente en %d ms');\n *   },\n *\n *   'demo Test with selector objects': function(browser) {\n *      browser.waitForElementPresent({\n *        selector: '#index-container',\n *        timeout: 1000\n *      });\n *\n *      browser.waitForElementPresent({\n *        selector: '#index-container',\n *        locateStrategy: 'css selector'\n *      }, 'Custom output message');\n *\n *      browser.waitForElementPresent({\n *        selector: '.container',\n *        index: 2,\n *        retryInterval: 100,\n *        abortOnFailure: true\n *      });\n *   }\n *\n *   'page object demo Test': function (browser) {\n *      var nightwatch = browser.page.nightwatch();\n *      nightwatch\n *        .navigate()\n *        .assert.titleContains('Nightwatch.js');\n *\n *      nightwatch.waitForElementPresent('@featuresList', function(result) {\n *        console.log(result);\n *      });\n *   }\n * }\n *\n * @method waitForElementPresent\n * @syntax .waitForElementPresent([using], selector, [timeout], [pollInterval], [abortOnAssertionFailure], [callback], [message]);\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {number} [time=waitForConditionTimeout] The total number of milliseconds to wait before failing.\n * @param {number} [poll=waitForConditionPollInterval] The number of milliseconds to wait between checks. You can use this only if you also specify the time parameter.\n * @param {boolean} [abortOnFailure=abortOnAssertionFailure] By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. To set this globally you can define a property `abortOnAssertionFailure` in your globals.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @param {string} [message] Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time (e.g. Element %s was not in the page for %d ms).\n * @sortIndex 0\n * @api protocol.waitforelements\n */\nclass WaitForElementPresent extends WaitForElement {\n  get retryOnSuccess() {\n    return false;\n  }\n\n  elementFound(result) {\n    const defaultMsg = 'Element <%s> was present after %d milliseconds.';\n\n    return this.pass(result, defaultMsg, this.executor.elapsedTime);\n  }\n}\n\nmodule.exports = WaitForElementPresent;\n"
  },
  {
    "path": "lib/api/element-commands/waitForElementVisible.js",
    "content": "const WaitForDisplayed = require('./_waitForDisplayed.js');\n\n/**\n * Waits a given time in milliseconds (default 5000ms) for an element to be visible in the page before performing any other commands or assertions.\n *\n * If the element fails to be present and visible in the specified amount of time,  the test will be marked as failed, and ordinarily, the subsequent steps/commands within the test-case/section will not be performed. However, you have the option to prevent the remaining steps/commands from being skipped by setting `abortOnFailure` to `false`.\n *\n * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file.\n *\n * Similarly, a default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds).\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     // with default implicit timeout of 5000ms (can be overwritten in settings under 'globals.waitForConditionTimeout')\n *     browser.waitForElementVisible('#index-container');\n *\n *     // specify the locate strategy (css selector/xpath) as the first argument\n *     browser.waitForElementVisible('css selector', '#index-container');\n *\n *     // with explicit timeout (in milliseconds)\n *     browser.waitForElementVisible('#index-container', 1000);\n *\n *     // continue if failed\n *     browser.waitForElementVisible('#index-container', 1000, false);\n *\n *     // with callback\n *     browser.waitForElementVisible('#index-container', 1000, function() {\n *       // do something while we're here\n *     });\n *\n *     // with custom output message - the locate strategy is required\n *     browser.waitForElementVisible('css selector', '#index-container', 'The index container is found.');\n *\n *     // with custom Spanish message\n *     browser.waitForElementVisible('#index-container', 1000, 'elemento %s no era presente en %d ms');\n *\n *     // many combinations possible - the message is always the last argument\n *     browser.waitForElementVisible('#index-container', 1000, false, function() {}, 'elemento %s no era visible en %d ms');\n *   },\n *\n *   'demo Test with selector objects': function(browser) {\n *      browser.waitForElementVisible({\n *        selector: '#index-container',\n *        timeout: 1000\n *      });\n *\n *      browser.waitForElementVisible({\n *        selector: '#index-container',\n *        locateStrategy: 'css selector'\n *      }, 'Custom output message');\n *\n *      browser.waitForElementVisible({\n *        selector: '.container',\n *        index: 2,\n *        retryInterval: 100,\n *        abortOnFailure: true\n *      });\n *   }\n *\n *   'page object demo Test': function (browser) {\n *      var nightwatch = browser.page.nightwatch();\n *      nightwatch\n *        .navigate()\n *        .assert.titleContains('Nightwatch.js');\n *\n *      nightwatch.waitForElementVisible('@featuresList', function(result) {\n *        console.log(result);\n *      });\n *   }\n * }\n *\n * @syntax .waitForElementVisible([using], selector, [timeout], [pollInterval], [abortOnAssertionFailure], [callback], [message]);\n * @method waitForElementVisible\n * @param {string} [using] The locator strategy to use. See [W3C Webdriver - locator strategies](https://www.w3.org/TR/webdriver/#locator-strategies)\n * @param {string|object} selector The selector (CSS/Xpath) used to locate the element. Can either be a string or an object which specifies [element properties](https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties).\n * @param {number} [time=waitForConditionTimeout] The total number of milliseconds to wait before failing.\n * @param {number} [poll=waitForConditionPollInterval] The number of milliseconds to wait between checks. You can use this only if you also specify the time parameter.\n * @param {boolean} [abortOnFailure=abortOnAssertionFailure] By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. To set this globally you can define a property `abortOnAssertionFailure` in your globals.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @param {string} [message] Optional message to be shown in the output; the message supports two placeholders: %s for current selector and %d for the time (e.g. Element %s was not in the page for %d ms).\n * @sortIndex 20\n * @api protocol.waitforelements\n */\nclass WaitForElementVisible extends WaitForDisplayed {\n  constructor(opts) {\n    super(opts);\n\n    this.expectedValue = 'visible';\n  }\n\n  shouldRetryAction(elementVisible) {\n    return !elementVisible;\n  }\n\n  elementVisible(response) {\n    const defaultMsg = 'Element <%s> was visible after %d milliseconds.';\n\n    return this.pass(response, defaultMsg, this.executor.elapsedTime);\n  }\n\n  elementNotVisible(response) {\n    const defaultMsg = 'Timed out while waiting for element <%s> to be visible for %d milliseconds.';\n\n    return this.fail(response, 'not visible', this.expectedValue, defaultMsg);\n  }\n}\n\n\nmodule.exports = WaitForElementVisible;\n"
  },
  {
    "path": "lib/api/expect/_baseExpect.js",
    "content": "const EventEmitter = require('events');\nconst chaiNightwatch = require('chai-nightwatch');\nconst {Logger, format, createPromise} = require('../../utils');\n\nconst BaseAssertion = require('./assertions/_baseAssertion.js');\n\nclass ValueExpectAssertion extends BaseAssertion {\n  getMessage(negate) {\n    if (this.emitter.getMessage) {\n      return this.emitter.getMessage(negate);\n    }\n\n    const initialMessage = this.message || `Expected ${this.expectCommandName}`;\n\n    return `${initialMessage} to ${negate ? ' not' : ''}%s`;\n  }\n\n  init() {\n    super.init();\n\n    this.flag('valueFlag', true);\n    this.message = this.getMessage(this.negate);\n    this.start();\n  }\n\n  executeCommand() {\n    return Promise.resolve({\n      value: this.emitter.resultValue\n    });\n  }\n\n  onResultSuccess() {\n    if (this.retries > 0 && this.negate) {\n      return;\n    }\n\n    this.addExpectedInMessagePart();\n  }\n\n  onResultFailed() {\n    this.passed = false;\n  }\n\n  formatMessage() {\n    if (this.element) {\n      let {selector, name} = this.element;\n      let nameStr = '';\n\n      if (name) {\n        nameStr = `@${name} `;\n      }\n\n      selector = selector ? `${nameStr}<${selector}>` : `<${this.element.toString()}>`;\n\n      this.message = format(this.message, selector, this.elapsedTime);\n    }\n\n    super.formatMessage();\n  }\n\n}\n\nclass ExpectInstance extends EventEmitter {\n\n  flag(...args) {\n    return chaiNightwatch.flag(this.instance, ...args);\n  }\n\n  get client() {\n    return this.__nightwatchInstance;\n  }\n\n  get commandFileName() {\n    return this.__commandName;\n  }\n\n  get commandArgs() {\n    return this.__commandArgs;\n  }\n\n  get transport() {\n    return this.client.transport;\n  }\n\n  get transportActions() {\n    return this.client.transportActions;\n  }\n\n  get elementLocator() {\n    return this.client.elementLocator;\n  }\n\n  get instance() {\n    return this.__instance;\n  }\n\n  get stackTrace() {\n    return this.__stackTrace;\n  }\n\n  set stackTrace(val) {\n    this.__stackTrace = val;\n  }\n\n  toString() {\n    return `${this.constructor.name} [name=expect.${this.commandFileName}]`;\n  }\n\n  constructor({commandName, nightwatchInstance, commandArgs}) {\n    super();\n\n    this.__commandName = commandName;\n    this.__commandArgs = commandArgs;\n    this.__nightwatchInstance = nightwatchInstance;\n\n    this.startTime = null;\n    this.resolve = null;\n    this.reject = null;\n\n    this.createInstance();\n\n    if (!this.hasAssertions) {\n      this.initAssertion();\n    }\n  }\n\n  /**\n   * Main entry point\n   *\n   * @param args\n   */\n  run(...args) {\n    this.startTime = new Date().getTime();\n\n    const promise = this.command(...args);\n    this.handleCommandPromise(promise);\n  }\n\n  createLocalPromise() {\n    return new Promise((resolve, reject) => {\n      this.resolve = resolve;\n      this.reject = reject;\n    });\n  }\n\n  createInstance() {\n    this.promise = this.createLocalPromise();\n\n    this.deferred = {\n      commandName: this.commandFileName\n    };\n\n    this.__instance = chaiNightwatch.expect((resolve, reject) => {\n      this.deferred.resolve = resolve;\n      this.deferred.reject = reject;\n    });\n\n    this.flag('deferred', this.deferred);\n\n    if (!this.hasAssertions) {\n      this.flag('valueFlag', true);\n    }\n    this.flag('emitter', this);\n    this.flag('api', this.client.api);\n    this.flag('promise', this.promise);\n  }\n\n  createRetryPromise() {\n    this.promise = this.createLocalPromise();\n    this.flag('promise', this.promise);\n\n    return this.promise;\n  }\n\n  retryCommand() {\n    const promise = this.command(...this.commandArgs);\n    this.handleCommandPromise(promise);\n  }\n\n  /**\n   * @override\n   * @param [args]\n   * @return {Promise}\n   */\n  command(...args) {\n    throw new Error(`The expect command \"${this.commandFileName}\" should have a \".command()\" method defined.`);\n  }\n\n  /**\n   * @param {Promise} promise\n   */\n  handleCommandPromise(promise) {\n    promise\n      .then(result => {\n        this.resultValue = result && result.value || result;\n\n        return this.resolve(this.resultValue);\n      })\n      .catch(result => {\n        if ((result instanceof Error) && result.name !== 'NoSuchElementError') {\n          Logger.error(result);\n        }\n        this.reject(result);\n      });\n  }\n\n  checkFlags() {\n    if (!this.needsFlags) {\n      return true;\n    }\n\n    if (this.flag('component')) {\n      return true;\n    }\n\n    return this.needsFlags.some((flag) => this.flag(`${flag}Flag`) !== undefined || this.flag(flag) !== undefined);\n  }\n\n  initAssertion({AssertModule = ValueExpectAssertion, message = null, args = []} = {}) {\n    const nightwatchInstance = this.client;\n    const assertion = new AssertModule({\n      nightwatchInstance,\n      chaiExpect: this.instance,\n      message,\n      expectCommandName: this.commandFileName\n    });\n    assertion.init(...args);\n\n    this.instance.assertion = assertion;\n  }\n}\n\nmodule.exports = ExpectInstance;\n"
  },
  {
    "path": "lib/api/expect/assertions/_baseAssertion.js",
    "content": "/**\n * Abstract assertion class that will subclass all defined Chai assertions\n *\n * All assertions must implement the following api:\n *\n * - @type {function}\n *   executeCommand\n * - @type {string}\n *   elementFound\n * - @type {function}\n *   elementNotFound\n * - @type {function}\n *   retryCommand\n * - @type {string}\n *   expected\n * - @type {string}\n *   actual\n * - @type {string}\n *   message\n * - @type {boolean}\n *   passed\n *\n * @constructor\n */\nconst assert = require('assert');\nconst {flag} = require('chai-nightwatch').util;\nconst Utils = require('../../../utils');\nconst {AssertionRunner, getExpectedMessage} = require('../../../assertion');\nconst {Logger, isUndefined} = Utils;\n\nclass BaseAssertion {\n  static get AssertionType () {\n    return {\n      PROPERTY: 'property',\n      METHOD: 'method'\n    };\n  }\n\n  static get ASSERT_FLAGS() {\n    return [\n      'be',\n      'that',\n      'and',\n      'have',\n      'which',\n      'equal',\n      'contains',\n      'startsWith',\n      'endsWith',\n      'matches',\n      'before',\n      'after',\n      'waitFor'\n    ];\n  }\n\n  get transport() {\n    return this.client.transport;\n  }\n\n  get reporter() {\n    return this.client.reporter;\n  }\n\n  get transportActions() {\n    return this.emitter.transportActions;\n  }\n\n  get assertion() {\n    return this.runner.assertion;\n  }\n\n  get selector() {\n    return this.flag('element') && this.flag('element').selector;\n  }\n\n  /**\n   * @override\n   * @return {Promise}\n   */\n  executeCommand() {}\n\n  /**\n   * @override\n   */\n  onResultSuccess() {}\n\n  /**\n   * @override\n   */\n  onResultFailed() {}\n\n  flag(key, value) {\n    if (typeof value == 'undefined') {\n      return flag(this.chaiExpect, key);\n    }\n\n    flag(this.chaiExpect, key, value);\n\n    return this;\n  }\n\n  getFlags() {\n    return flag(this.chaiExpect);\n  }\n\n  setFlags() {\n    this.emitter = this.flag('emitter');\n    this.setDeepEqualFlag();\n\n    this.element = this.flag('element');\n    if (this.element) {\n      const {timeout, retryInterval, abortOnFailure, message} = this.element;\n      if (Utils.isNumber(timeout)) {\n        this.waitForMs = timeout;\n        this.flag('waitFor', this.waitForMs);\n      }\n\n      if (Utils.isNumber(retryInterval)) {\n        this.retryInterval = retryInterval;\n      }\n\n      if (Utils.isBoolean(abortOnFailure)) {\n        this.abortOnFailure = abortOnFailure;\n      }\n\n      if (message) {\n        this.message = message;\n        this.hasCustomMessage = true;\n      }\n    }\n  }\n\n  /**\n   * @param {Nightwatch} nightwatchInstance\n   * @param {chai.Assertion} chaiExpect\n   * @param {string} expectCommandName\n   * @param {string} message\n   */\n  constructor({nightwatchInstance, chaiExpect, expectCommandName, message = ''}) {\n    this.client = nightwatchInstance;\n    this.chaiExpect = chaiExpect;\n    this.expectCommandName = expectCommandName;\n    this.message = message;\n  }\n\n  init() {\n    const {waitForConditionTimeout, waitForConditionPollInterval, abortOnAssertionFailure} = this.client.api.globals;\n\n    const assertions = this.flag('assertions') || 0;\n    this.flag('assertions', assertions + 1);\n\n    this.promise = this.flag('promise');\n    this.setFlags();\n    this.setNegate();\n    this.setDeepEqualFlag();\n    this.setWaitForFlag(waitForConditionTimeout);\n\n    this.retryInterval  = waitForConditionPollInterval || 500;\n    this.abortOnFailure = abortOnAssertionFailure;\n\n    this.retries = 0;\n    this.passed = undefined;\n    this.actual = undefined;\n    this.expected = undefined;\n    this.resultValue = undefined;\n    this.messageParts = [];\n    this.flags = [];\n  }\n\n  start() {\n    this.promise.then(this.onPromiseResolved.bind(this), this.onPromiseRejected.bind(this));\n  }\n\n  getResultValue(result) {\n    if (result && (result.error instanceof Error)) {\n      return null;\n    }\n\n    return result.value;\n  }\n\n  getResultStatus(result) {\n    if (result && (result.error instanceof Error)) {\n      return -1;\n    }\n\n    return result.status;\n  }\n\n  getResultError(result) {\n    if (result && (result.error instanceof Error)) {\n      return result.error;\n    }\n\n    return null;\n  }\n\n  onPromiseResolved() {\n    this.setFlags();\n\n    this.executeCommand().then(result => {\n      if (isUndefined(result)) {\n        return this.onPromiseRejected(new Error('Unknown error'));\n      }\n\n      this.onExecuteCommandResult(result);\n    });\n  }\n\n  onExecuteCommandResult(result) {\n    this.resultValue = this.getResultValue(result);\n    this.resultStatus = this.getResultStatus(result);\n    this.resultErrorStatus = this.getResultError(result);\n\n    this.processFlags();\n    this.onResultSuccess();\n\n    if ((this.passed === false) && this.shouldRetry()) {\n      this.scheduleRetry();\n    } else {\n      this.done();\n    }\n  }\n\n  elementNotFoundError(response) {\n    return response instanceof Error && response.name === 'NotFoundError';\n  }\n\n  onPromiseRejected(response) {\n    if (response instanceof Error) {\n      this.resultErrorStatus = response;\n    }\n\n    this.processFlags();\n    this.setFlags();\n\n    if (this.shouldRetry() && !this.negate) {\n      this.scheduleRetry();\n\n      return;\n    }\n\n    this.addExpectedInMessagePart();\n\n    let notFoundStr = ' - element was not found';\n    if (this.elementNotFoundError(response)) {\n      notFoundStr = ` - ${response.message}`;\n    }\n\n    if (this.hasCustomMessage) {\n      this.message += notFoundStr;\n    } else {\n      this.messageParts.push(notFoundStr);\n    }\n\n    this.actual = this.getActual('not present');\n    if (!this.expected) {\n      this.expected = 'present';\n    }\n\n    this.onResultFailed();\n    this.done();\n  }\n\n  getActual(actual) {\n    if (this.resultErrorStatus && this.resultErrorStatus.name !== 'NoSuchElementError') {\n      return `[${this.resultErrorStatus.name}]`;\n    }\n\n    return actual;\n  }\n\n  processFlags() {\n    this.getFlags().forEach((value, key) => {\n      if (BaseAssertion.ASSERT_FLAGS.includes(key) && Utils.isFunction(this[`@${key}Flag`])) {\n        this.flags.push(key);\n        this[`@${key}Flag`](value);\n      }\n    });\n  }\n\n  hasFlag(type) {\n    return this.flags.includes(type);\n  }\n\n  done() {\n    this.formatMessage();\n    this.runAssertion();\n  }\n\n  runAssertion() {\n    const stackTrace = this.emitter.stackTrace;\n    const reporter = this.client.reporter;\n\n    const {passed, actual, expected, message, abortOnFailure} = this;\n\n    if (passed === undefined) {\n      const err = new Error(`Incomplete expect assertion for \"expect.${this.emitter.commandFileName}()\". Please consult the docs at https://nightwatchjs.org/api/expect/`);\n      err.isExpect = true;\n      this.emitter.emit('error', err);\n\n      return this;\n    }\n\n    this.runner = new AssertionRunner({\n      passed,\n      addExpected: false,\n      err: {\n        expected, actual\n      }, message, abortOnFailure, stackTrace, reporter\n    });\n\n    this.runner.run()\n      .catch(err => (err))\n      .then(result => {\n        const isError = result instanceof Error;\n\n        if (isError) {\n          result.isExpect = true;\n\n          if (this.resultErrorStatus && this.reporter) {\n            this.reporter.registerTestError(this.resultErrorStatus);\n          }\n\n          this.emitter.emit('error', result, this.abortOnFailure);\n        } else {\n          const assertions = this.flag('assertions');\n\n          if (this.flag('and') && assertions > 1) {\n            this.flag('and', null);\n            this.flag('assertions', assertions - 1);\n\n            return;\n          }\n\n          this.emitter.emit('complete', result);\n        }\n      });\n  }\n\n  getResult(value, fn) {\n    const result = fn.call(this);\n    this.setNegate();\n\n    return this.negate ? !result : result;\n  }\n\n  shouldRetry() {\n    if (!this.waitForMs || this.emitter.retryUnavailable) {\n      return false;\n    }\n\n    this.elapsedTime = this.getElapsedTime();\n\n    return (this.elapsedTime < this.waitForMs);\n  }\n\n  getElapsedTime() {\n    const timeNow = new Date().getTime();\n\n    return timeNow - this.emitter.startTime;\n  }\n\n  scheduleRetry() {\n    this.retries++;\n\n    setTimeout(this.retryCommand.bind(this), this.retryInterval);\n  }\n\n  formatMessage() {\n    if (this.passed === false) {\n      this.addExpectedMessage();\n    }\n\n    this.addTimeMessagePart();\n\n    if (!this.hasCustomMessage) {\n      this.message += this.messageParts.join('');\n    }\n  }\n\n  '@containsFlag'(value) {\n    const verb = (this.hasFlag('that') || this.hasFlag('which')) ? 'contains' : 'contain';\n\n    this.conditionFlag(value, function() {\n      if (!Utils.isString(this.resultValue) && !Array.isArray(this.resultValue)) {\n        Logger.warn(`Unexpected non-string or array result value returned for contains: ${this.resultValue}`);\n\n        return false;\n      }\n\n      return this.resultValue.indexOf(value) > -1;\n    }, [`not ${verb}`, verb]);\n\n    return this;\n  }\n\n  '@startsWithFlag'(value) {\n    const verb = (this.hasFlag('that') || this.hasFlag('which')) ? 'starts with' : 'start with';\n\n    this.conditionFlag(value, function() {\n      if (!Utils.isString(this.resultValue)) {\n        Logger.warn(`Unexpected non-string result value returned for startsWith: ${this.resultValue}`);\n\n        return false;\n      }\n\n      return this.resultValue.indexOf(value) === 0;\n    }, [\n      `not ${verb}`,\n      verb\n    ]);\n\n    return this;\n  }\n\n  '@endsWithFlag'(value) {\n    const verb = (this.hasFlag('that') || this.hasFlag('which')) ? 'ends with' : 'end with';\n\n    this.conditionFlag(value, function() {\n      if (!Utils.isString(this.resultValue)) {\n        Logger.warn(`Unexpected non-string result value returned for endsWith: ${this.resultValue}`);\n\n        return false;\n      }\n\n      return (this.resultValue.lastIndexOf(value) + value.length) === this.resultValue.length;\n    }, [\n      `not ${verb}`,\n      verb\n    ]);\n\n    return this;\n  }\n\n  '@equalFlag'(value) {\n    let verb;\n    if (this.hasFlag('have')) {\n      verb = (this.hasFlag('that') || this.hasFlag('which')) ? 'equals' : 'equal to';\n    } else {\n      verb = 'equal';\n    }\n\n    if (this.deepEqual) {\n      verb = `deep ${verb}`;\n    }\n\n    this.conditionFlag(value, function() {\n      if (this.deepEqual || Utils.isObject(value)) {\n        try {\n          assert.deepStrictEqual(value, this.resultValue);\n\n          return true;\n        } catch (err) {\n          return false;\n        }\n      }\n\n      return this.resultValue === value;\n    }, [\n      `not ${verb}`,\n      verb\n    ]);\n\n    return this;\n  }\n\n  '@matchesFlag'(re) {\n    const adverb = this.hasFlag('that') || this.hasFlag('which');\n    const verb = adverb ? 'matches' : 'match';\n\n    this.conditionFlag(re, function() {\n      return re.test(this.resultValue);\n    }, [\n      (adverb ? 'does ' : '') + 'not match',\n      verb\n    ]);\n\n    return this;\n  }\n\n  conditionFlag(value, conditionFn, arrverb) {\n    this.passed = this.getResult(value, conditionFn);\n\n    let verb = this.negate ? arrverb[0] : arrverb[1];\n    this.expected = `${verb} '${value}'`;\n    this.actual = this.resultValue;\n\n    if (this.retries > 0) {\n      return;\n    }\n\n    const needsSpace = this.messageParts.length === 0 ? true : this.messageParts[this.messageParts.length - 1].slice(-1) !== ' ';\n    if (needsSpace) {\n      verb = ' ' + verb;\n    }\n\n    if (!this.hasCustomMessage) {\n      this.messageParts.push(`${verb}: ${Logger.colors.brown('\"' + value + '\"')}`);\n    }\n  }\n\n  setNegate() {\n    this.negate = this.flag('negate') || false;\n\n    return this;\n  }\n\n  setDeepEqualFlag() {\n    this.deepEqual = this.flag('deep') || false;\n\n    return this;\n  }\n\n  setWaitForFlag(waitForConditionTimeout) {\n    this.waitForMs = waitForConditionTimeout || null;\n    if (this.waitForMs) {\n      this.flag('waitFor', this.waitForMs);\n    }\n\n    return this;\n  }\n\n  '@beforeFlag'(value) {}\n\n  '@afterFlag'(value) {}\n\n  '@haveFlag'(value) {}\n\n  '@waitForFlag'(value) {\n    if (this.waitForMs !== value) {\n      this.waitForMs = value;\n    }\n  }\n\n  '@andFlag'() {\n    if (this.retries > 0) {\n      return;\n    }\n\n    if (!this.hasCustomMessage) {\n      this.messageParts.push(' and ');\n    }\n\n    return this;\n  }\n\n  '@thatFlag'() {\n    if (this.retries > 0) {\n      return;\n    }\n\n    if (!this.hasCustomMessage) {\n      this.messageParts.push(' that ');\n    }\n\n    return this;\n  }\n\n  '@whichFlag'() {\n    if (this.retries > 0) {\n      return;\n    }\n\n    if (!this.hasCustomMessage) {\n      this.messageParts.push(' which ');\n    }\n\n    return this;\n  }\n\n  '@beFlag'() {}\n\n  addTimeMessagePart() {\n    this.elapsedTime = this.getElapsedTime();\n    const timeStr = Logger.colors.stack_trace(' (' + this.elapsedTime + 'ms)');\n\n    if (this.hasCustomMessage) {\n      this.message += timeStr;\n    } else {\n      this.messageParts.push(timeStr);\n    }\n  }\n\n  addExpectedMessage() {\n    const {actual, expected} = this;\n    const message = getExpectedMessage({\n      actual, expected\n    });\n\n    if (this.hasCustomMessage) {\n      this.message += message;\n    } else {\n      this.messageParts.push(message);\n    }\n  }\n\n  addExpectedInMessagePart() {\n    const expectedIn = ` in ${this.waitForMs}ms`;\n\n    if (!this.hasCustomMessage && (this.flag('before') || this.flag('after')) && !this.messageParts.includes(expectedIn)) {\n      this.messageParts.push(expectedIn);\n    }\n  }\n\n  hasCondition() {\n    return (\n      this.hasFlag('contains') ||\n      this.hasFlag('equal') ||\n      this.hasFlag('matches') ||\n      this.hasFlag('startsWith') ||\n      this.hasFlag('endsWith')\n    );\n  }\n\n  retryCommand() {\n    this.promise = this.emitter.createRetryPromise();\n    this.promise.then(this.onPromiseResolved.bind(this), this.onPromiseRejected.bind(this));\n    this.emitter.retryCommand();\n  }\n}\n\nmodule.exports = BaseAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/_element-assertion.js",
    "content": "const Utils = require('../../../../utils');\nconst BaseAssertion = require('../_baseAssertion.js');\n\nclass ExpectElement extends BaseAssertion {\n  /**\n   * @override\n   */\n  onResultSuccess() {}\n\n  /**\n   * @override\n   */\n  onResultFailed() {}\n\n  onPromiseResolved(value) {\n    if (value) {\n      if (Utils.isObject(value) && value.elementId) {\n        this.elementId = value.elementId;\n      } else {\n        this.elementId = this.transport.getElementId(value);\n      }\n    }\n\n    super.onPromiseResolved();\n  }\n\n  formatMessage() {\n    let {selector, name} = this.element;\n    let nameStr = '';\n\n    if (name) {\n      nameStr = `@${name} `;\n    }\n\n    selector = selector ? `${nameStr}<${selector}>` : `<${this.element.toString()}>`;\n\n\n    this.message = Utils.format(this.message, selector, this.elapsedTime);\n\n    super.formatMessage();\n  }\n\n  /**\n   *\n   * @param {String} protocolAction\n   * @param {Array} [args]\n   * @return {Promise}\n   */\n  executeProtocolAction(protocolAction, args = []) {\n    if (!Array.isArray(args)) {\n      args = [args];\n    }\n\n    const {sessionId, element} = this.emitter;\n    if (element && element.webElement) {\n      this.elementId = element.resolvedElement || element.webElement;\n    }\n    args.unshift(this.elementId);\n\n    if (sessionId) {\n      return this.transportActions[protocolAction](args, sessionId);\n    }\n\n    return this.transportActions[protocolAction](...args);\n  }\n\n  retryCommand() {\n    if (this.shouldRetryLocateElement()) {\n      this.resultErrorStatus = null;\n      this.elementId = null;\n      this.resultValue = null;\n      this.promise = this.emitter.createRetryPromise();\n      this.promise.then(this.onPromiseResolved.bind(this), this.onPromiseRejected.bind(this));\n      this.emitter.retryCommand();\n    } else {\n      this.onPromiseResolved();\n    }\n  }\n\n  shouldRetryLocateElement() {\n    return !this.elementId || this.isRetryableElementError();\n  }\n\n  isRetryableElementError() {\n    return this.transport.isRetryableElementError(this.resultErrorStatus || this.resultStatus);\n  }\n\n  isComponent() {\n    return this.flag('component') === true;\n  }\n}\n\nmodule.exports = ExpectElement;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/active.js",
    "content": "/**\n * Property that checks if an element is active in the DOM.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('#main').to.be.active;\n *   browser.expect.element('#main').to.not.be.active;\n *   browser.expect.element('#main').to.be.active.before(100);\n * };\n *\n *\n * @method active\n * @display .active\n * @since v1.1\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass ActiveAssertion extends BaseAssertion {\n  static get assertionType() {\n    return BaseAssertion.AssertionType.PROPERTY;\n  }\n\n  init() {\n    super.init();\n\n    this.flag('active', true);\n    this.message = 'Expected element %s to ' + (this.negate ? 'not be active' : 'be active');\n    this.start();\n  }\n\n  executeCommand() {\n    return this.executeProtocolAction('getActiveElement');\n  }\n\n  compareElementIds() {\n    return this.resultValue === this.elementId;\n  }\n\n  onResultSuccess() {\n    const result = this.compareElementIds();\n\n    this.passed = this.negate ? result === false : result;\n    this.expected = this.negate ? 'not active' : 'active';\n    this.actual = result ? 'active' : 'not active';\n\n    this.addExpectedInMessagePart();\n  }\n\n  onResultFailed() {\n    this.passed = this.negate;\n  }\n\n}\n\nmodule.exports = ActiveAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/attribute.js",
    "content": "/**\n * Checks if a given attribute of an element exists and optionally if it has the expected value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('body').to.have.attribute('data-attr');\n *   browser.expect.element('body').to.not.have.attribute('data-attr');\n *   browser.expect.element('body').to.not.have.attribute('data-attr', 'Testing if body does not have data-attr');\n *   browser.expect.element('body').to.have.attribute('data-attr').before(100);\n *   browser.expect.element('body').to.have.attribute('data-attr')\n *     .equals('some attribute');\n *   browser.expect.element('body').to.have.attribute('data-attr')\n *     .not.equals('other attribute');\n *   browser.expect.element('body').to.have.attribute('data-attr')\n *     .which.contains('something');\n *   browser.expect.element('body').to.have.attribute('data-attr')\n *     .which.matches(/^something\\ else/);\n * };\n *\n *\n * @method attribute\n * @param {string} attribute The attribute name\n * @param {string} [message] Optional log message to display in the output. If missing, one is displayed by default.\n * @display expect.element.attribute(name)\n * @syntax browser.expect.element(selector).to.have.attribute(attribute)\n * @since v0.7\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass AttributeAssertion extends BaseAssertion {\n  static get assertionType() {\n    return BaseAssertion.AssertionType.METHOD;\n  }\n\n  init(attribute, msg) {\n    super.init();\n\n    this.flag('attributeFlag', true);\n    this.attribute = attribute;\n    this.hasCustomMessage = typeof msg != 'undefined';\n    this.message = msg || 'Expected element %s to ' + (this.negate ? 'not have' : 'have') + ' attribute \"' + attribute + '\"';\n\n    this.start();\n  }\n\n  executeCommand() {\n    return this.executeProtocolAction('getElementAttribute', [this.attribute]);\n  }\n\n\n  onExecuteCommandResult(result) {\n    this.resultValue = this.getResultValue(result);\n    this.resultStatus = this.getResultStatus(result);\n    this.resultErrorStatus = this.getResultError(result);\n\n    if (this.resultValue === null && !this.resultErrorStatus) {\n      this.attributeNotFound();\n\n      return;\n    }\n\n    this.processFlags();\n    this.onResultSuccess();\n\n    if (!this.passed && this.shouldRetry()) {\n      this.scheduleRetry();\n    } else {\n      this.done();\n    }\n  }\n\n  onResultSuccess() {\n    if (this.retries > 0 && this.negate) {\n      return;\n    }\n\n    if (!this.hasCondition()) {\n      this.passed = !this.negate;\n      this.expected = this.negate ? 'not found' : 'found';\n      this.actual = 'found';\n    }\n\n    this.addExpectedInMessagePart();\n  }\n\n  attributeNotFound() {\n    this.processFlags();\n    this.passed = this.hasCondition() ? false : this.negate;\n\n    if (!this.passed && this.shouldRetry()) {\n      this.scheduleRetry();\n    } else {\n      this.addExpectedInMessagePart();\n      if (!this.hasCondition()) {\n        this.expected = this.negate ? 'not found' : 'found';\n        this.actual = this.getActual('not found');\n      }\n\n      if (!this.negate) {\n        const attrNotFound = ' - attribute was not found';\n\n        if (this.hasCustomMessage) {\n          this.message += attrNotFound;\n        } else {\n          this.messageParts.push(attrNotFound);\n        }\n      }\n\n      this.done();\n    }\n  }\n\n  onResultFailed() {\n    this.passed = false;\n  }\n}\n\n\n\nmodule.exports = AttributeAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/css.js",
    "content": "/**\n * Checks a given css property of an element exists and optionally if it has the expected value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('#main').to.have.css('display');\n *   browser.expect.element('#main').to.have.css('display', 'Testing for display');\n *   browser.expect.element('#main').to.not.have.css('display');\n *   browser.expect.element('#main').to.have.css('display').before(100);\n *   browser.expect.element('#main').to.have.css('display').which.equals('block');\n *   browser.expect.element('#main').to.have.css('display').which.contains('some value');\n *   browser.expect.element('#main').to.have.css('display').which.matches(/some\\ value/);\n * };\n *\n *\n * @method css\n * @param {string} property The css property name\n * @param {string} [message] Optional log message to display in the output. If missing, one is displayed by default.\n * @display .css(property)\n * @since v0.7\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass CssAssertion extends BaseAssertion {\n  static get assertionType() {\n    return BaseAssertion.AssertionType.METHOD;\n  }\n\n  init(property, msg) {\n    super.init();\n\n    this.cssProperty = property;\n    this.flag('cssFlag', true);\n    this.hasCustomMessage = typeof msg != 'undefined';\n    this.message = msg || 'Expected element %s to ' + (this.negate ? 'not have' : 'have') + ' css property \"' + property + '\"';\n    this.start();\n  }\n\n  executeCommand() {\n    return this.executeProtocolAction('getElementCSSValue', [this.cssProperty]);\n  }\n\n  '@haveFlag'() {\n    this.passed = this.negate ? (this.resultValue === '') : (this.resultValue !== '');\n    this.expected = this.negate ? 'not present' : 'present';\n    this.actual = this.resultValue === '' ? 'not present' : 'present';\n  }\n\n  onResultSuccess() {\n    if (this.retries > 0 && this.negate) {\n      return;\n    }\n\n    this.addExpectedInMessagePart();\n  }\n\n  onResultFailed() {\n    this.passed = false;\n  }\n}\n\nmodule.exports = CssAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/enabled.js",
    "content": "/**\n * Property that checks if an element is currently enabled.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('#weblogin').to.be.enabled;\n *   browser.expect.element('#main').to.not.be.enabled;\n *   browser.expect.element('#main').to.be.enabled.before(100);\n * };\n *\n *\n * @method enabled\n * @display .enabled\n * @since v0.7\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass EnabledAssertion extends BaseAssertion {\n  static get assertionType() {\n    return BaseAssertion.AssertionType.PROPERTY;\n  }\n\n  init() {\n    super.init();\n\n    this.message = 'Expected element %s to ' + (this.negate ? 'not be enabled' : 'be enabled');\n    this.flag('enabledFlag', true);\n    this.start();\n  }\n\n  executeCommand() {\n    return this.executeProtocolAction('isElementEnabled');\n  }\n\n  onResultSuccess() {\n    if (this.retries > 0 && this.negate) {\n      return;\n    }\n\n    this.passed = this.negate ? !this.resultValue : this.resultValue;\n    this.expected = this.negate ? 'not enabled' : 'enabled';\n    this.actual = this.resultValue ? 'enabled' : 'not enabled';\n\n    this.addExpectedInMessagePart();\n  }\n\n  onResultFailed() {\n    this.passed = false;\n    this.expected = this.negate ? 'not enabled' : 'enabled';\n    this.actual = 'not found';\n  }\n}\n\n\nmodule.exports = EnabledAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/present.js",
    "content": "/**\n * Property that checks if an element is present in the DOM.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('#main').to.be.present;\n *   browser.expect.element('#main').to.not.be.present;\n *   browser.expect.element('#main').to.be.present.before(100);\n * };\n *\n *\n * @method present\n * @display .present\n * @since v0.7\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass PresentAssertion extends BaseAssertion {\n  static get assertionType() {\n    return BaseAssertion.AssertionType.PROPERTY;\n  }\n\n  isElementNotFoundError() {\n    return this.resultErrorStatus.name === 'NoSuchElementError';\n  }\n\n  init() {\n    super.init();\n\n    this.flag('present', true);\n    this.message = 'Expected element %s to ' + (this.negate ? 'not be present' : 'be present');\n    this.start();\n  }\n\n  executeCommand() {\n    return Promise.resolve(this.elementId);\n  }\n\n  onResultSuccess() {\n    this.passed = !this.negate;\n\n    if (!this.passed && this.shouldRetry()) {\n      return;\n    }\n\n    this.addExpectedInMessagePart();\n\n    if (this.negate) {\n      this.actual = 'present';\n      this.expected = 'not present';\n    }\n  }\n\n  onResultFailed() {\n    if ((this.resultErrorStatus instanceof Error) && !this.isElementNotFoundError()) {\n      this.passed = false;\n      this.actual = 'error while locating the element';\n      this.expected = this.negate ? 'not present' : 'present';\n\n      return;\n    }\n\n    this.expected = this.negate ? 'not present' : 'present';\n    this.passed = this.negate;\n  }\n\n  retryCommand() {\n    this.elementId = null;\n    super.retryCommand();\n  }\n}\n\nmodule.exports = PresentAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/property.js",
    "content": "/**\n * Checks if a given DOM property of an element has the expected value. For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('body').to.have.property('className').equals('test-class');\n *   browser.expect.element('body').to.have.property('className').matches(/^something\\ else/);\n *   browser.expect.element('body').to.not.have.property('classList').equals('test-class');\n *   browser.expect.element('body').to.have.property('classList').deep.equal(['class-one', 'class-two']);\n *   browser.expect.element('body').to.have.property('classList').contain('class-two');\n *   browser.expect.element('body').to.have.domProperty('classList').contain('class-two');\n * };\n *\n * @method property\n * @param {string} property The property name\n * @param {string} [message] Optional log message to display in the output. If missing, one is displayed by default.\n * @display .property(name)\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass PropertyAssertion extends BaseAssertion {\n  static get aliases() {\n    return ['domProperty'];\n  }\n\n  static get assertionType() {\n    return BaseAssertion.AssertionType.METHOD;\n  }\n\n  init(property, msg) {\n    super.init();\n\n    this.flag('attributeFlag', true);\n    this.property = property;\n    this.hasCustomMessage = typeof msg != 'undefined';\n    this.message = msg || `Expected element %s to ${this.negate ? 'not have' : 'have'} dom property \"${this.property}\"`;\n\n    this.start();\n  }\n\n  executeCommand() {\n    if (this.isComponent()) {\n      if (!this.hasCustomMessage) {\n        this.message = `Expected component %s to ${this.negate ? 'not have' : 'have'} property \"${this.property}\"`;\n      }\n      //return this.emitter.getComponentProperty(this.property);\n    }\n\n    return this.executeProtocolAction('getElementProperty', [this.property]);\n  }\n\n  hasProperty() {\n    if (this.flag('component') === true) {\n      return this.resultValue !== undefined;\n    }\n\n    return this.resultValue !== null;\n  }\n\n  onExecuteCommandResult(result) {\n    this.resultValue = this.getResultValue(result);\n    this.resultStatus = this.getResultStatus(result);\n    this.resultErrorStatus = this.getResultError(result);\n\n    if (!this.hasProperty() && !this.resultErrorStatus) {\n      this.propertyNotFound();\n\n      return;\n    }\n\n    this.processFlags();\n    this.onResultSuccess();\n\n    if (!this.passed && this.shouldRetry()) {\n      this.scheduleRetry();\n    } else {\n      this.done();\n    }\n  }\n\n  onResultSuccess() {\n    if (this.retries > 0 && this.negate) {\n      return;\n    }\n\n    if (!this.hasCondition()) {\n      this.passed = !this.negate;\n      this.expected = this.negate ? 'not found' : 'found';\n      this.actual = 'found';\n    }\n\n    this.addExpectedInMessagePart();\n  }\n\n  propertyNotFound() {\n    this.processFlags();\n    this.passed = this.hasCondition() ? false : this.negate;\n\n    if (!this.passed && this.shouldRetry()) {\n      this.scheduleRetry();\n    } else {\n      this.addExpectedInMessagePart();\n      if (!this.hasCondition()) {\n        this.actual = this.getActual('not found');\n      }\n\n      if (!this.negate) {\n        this.messageParts.push(' - property was not found');\n      }\n\n      this.done();\n    }\n  }\n\n  onResultFailed() {\n    this.passed = false;\n  }\n}\n\nmodule.exports = PropertyAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/selected.js",
    "content": "/**\n * Property that checks if an OPTION element, or an INPUT element of type checkbox or radio button is currently selected.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('#main').to.be.selected;\n *   browser.expect.element('#main').to.not.be.selected;\n *   browser.expect.element('#main').to.be.selected.before(100);\n * };\n *\n *\n * @method selected\n * @display .selected\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass SelectedAssertion extends BaseAssertion {\n  static get assertionType() {\n    return BaseAssertion.AssertionType.PROPERTY;\n  }\n\n  init() {\n    super.init();\n\n    this.message = 'Expected element %s to ' + (this.negate ? 'not be selected' : 'be selected');\n    this.flag('selectedFlag', true);\n    this.start();\n  }\n\n  executeCommand() {\n    return this.executeProtocolAction('isElementSelected');\n  }\n\n  onResultSuccess() {\n    if (this.retries > 0 && this.negate) {\n      return;\n    }\n\n    this.passed = this.negate ? !this.resultValue : this.resultValue;\n    this.expected = this.negate ? 'not selected' : 'selected';\n    this.actual = this.resultValue ? 'selected' : 'not selected';\n\n    this.addExpectedInMessagePart();\n  }\n\n  onResultFailed() {\n    this.passed = false;\n    this.expected = this.negate ? 'not selected' : 'selected';\n    this.actual = 'not found';\n  }\n\n}\n\n\nmodule.exports = SelectedAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/text.js",
    "content": "/**\n * Property that retrieves the text contained by an element. Can be chained to check if contains/equals/matches the specified text or regex.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('#main').text.to.equal('The Night Watch');\n *   browser.expect.element('#main').text.to.not.equal('The Night Watch');\n *   browser.expect.element('#main').text.to.equal('The Night Watch').before(100);\n *   browser.expect.element('#main').text.to.contain('The Night Watch');\n *   browser.expect.element('#main').text.to.match(/The\\ Night\\ Watch/);\n * };\n *\n *\n * @method text\n * @since v0.7\n * @display .text\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass TextAssertion extends BaseAssertion {\n  static get assertionType() {\n    return BaseAssertion.AssertionType.PROPERTY;\n  }\n\n  init() {\n    super.init();\n\n    this.flag('textFlag', true);\n    this.message = 'Expected element %s text to' + (this.negate ? ' not' : '');\n    this.start();\n  }\n\n  executeCommand() {\n    return this.executeProtocolAction('getElementText');\n  }\n\n  onResultSuccess() {\n    if (this.retries > 0 && this.negate) {\n      return;\n    }\n\n    this.addExpectedInMessagePart();\n  }\n\n  onResultFailed() {\n    this.passed = false;\n  }\n\n}\n\n\nmodule.exports = TextAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/type.js",
    "content": "/**\n * Checks if the type (i.e. tag name) of a specified element is of an expected value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('#q').to.be.an('input');\n *   browser.expect.element('#q').to.be.an('input', 'Testing if #q is an input');\n *   browser.expect.element('#w').to.be.a('span');\n * }\n *\n * @method a\n * @display .a(type)\n * @alias an\n * @since v0.7\n * @param {string} type The expected type\n * @param {string} [message] Optional log message to display in the output. If missing, one is displayed by default.\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass TypeAssertion extends BaseAssertion {\n  static get assertionName() {\n    return ['a', 'an'];\n  }\n\n  static get assertionType() {\n    return BaseAssertion.AssertionType.METHOD;\n  }\n\n  init(type, msg) {\n    super.init();\n\n    this.type = type;\n    this.article = ['a', 'e', 'i', 'o'].indexOf(type.toString().substring(0, 1)) > -1 ? 'an' : 'a';\n    this.hasCustomMessage = typeof msg != 'undefined';\n    this.flag('typeFlag', true);\n    this.message = msg || 'Expected element %s to ' + (this.negate ? 'not be' : 'be') + ' ' + this.article + ' ' + type;\n\n    this.start();\n  }\n\n  executeCommand() {\n    return this.executeProtocolAction('getElementTagName');\n  }\n\n  onResultSuccess() {\n    if (this.retries > 0 && this.negate) {\n      return;\n    }\n\n    if (this.type instanceof RegExp) {\n      const result = this.type.test(this.resultValue);\n      this.passed = this.negate ? !result : result;\n    } else {\n      this.type = this.type.toLowerCase();\n      this.resultValue = this.resultValue.toLowerCase();\n      this.passed = this.negate ? (this.resultValue !== this.type) : (this.resultValue === this.type);\n    }\n\n    this.expected = this.negate ? 'not be ' + this.article + ' ' + this.type : 'be ' + this.article + ' ' + this.type;\n    this.actual = this.resultValue;\n\n    this.addExpectedInMessagePart();\n  }\n\n  onResultFailed() {\n    this.passed = false;\n  }\n}\n\n\n\nmodule.exports = TypeAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/value.js",
    "content": "/**\n * Property that retrieves the value (i.e. the value attributed) of an element. Can be chained to check if contains/equals/matches the specified text or regex.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('#q').to.have.value.that.equals('search');\n *   browser.expect.element('#q').to.have.value.not.equals('search');\n *   browser.expect.element('#q').to.have.value.which.contains('search');\n *   browser.expect.element('#q').to.have.value.which.matches(/search/);\n * };\n *\n *\n * @display .value\n * @method value\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass ValueAssertion extends BaseAssertion {\n  static get assertionType() {\n    return BaseAssertion.AssertionType.PROPERTY;\n  }\n\n  init() {\n    super.init();\n\n    this.flag('valueFlag', true);\n\n    this.message = 'Expected element %s to have value' + (this.negate ? ' not' : '');\n    this.start();\n  }\n\n  executeCommand() {\n    return this.executeProtocolAction('getElementProperty', ['value']);\n  }\n\n  onExecuteCommandResult(result) {\n    this.resultValue = this.getResultValue(result);\n    this.resultStatus = this.getResultStatus(result);\n    this.resultErrorStatus = this.getResultError(result);\n\n    if (this.resultValue === null && !this.resultErrorStatus) {\n      this.valueNotFound();\n\n      return;\n    }\n\n    this.processFlags();\n    this.onResultSuccess();\n\n    if (!this.passed && this.shouldRetry()) {\n      this.scheduleRetry();\n    } else {\n      this.done();\n    }\n  }\n\n  onResultSuccess() {\n    if (this.retries > 0 && this.negate) {\n      return;\n    }\n\n    this.addExpectedInMessagePart();\n  }\n\n  valueNotFound() {\n    this.processFlags();\n    this.passed = this.hasCondition() ? false : this.negate;\n\n    if (!this.passed && this.shouldRetry()) {\n      this.scheduleRetry();\n    } else {\n      this.addExpectedInMessagePart();\n      if (!this.hasCondition()) {\n        this.expected = this.negate ? 'not found' : 'found';\n        this.actual = this.getActual('not found');\n      }\n\n      if (!this.negate) {\n        this.messageParts.push(' - value attribute was not found');\n      }\n      this.done();\n    }\n  }\n\n  onResultFailed() {\n    this.passed = false;\n  }\n}\n\nmodule.exports = ValueAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/element/visible.js",
    "content": "/**\n * Property that asserts the visibility of a specified element.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.element('#main').to.be.visible;\n *   browser.expect.element('#main').to.not.be.visible;\n *   browser.expect.element('#main').to.be.visible.before(100);\n * };\n *\n *\n * @display .visible\n * @method visible\n * @api expect.element\n */\nconst BaseAssertion = require('./_element-assertion.js');\n\nclass VisibleAssertion extends BaseAssertion {\n  static get assertionType() {\n    return BaseAssertion.AssertionType.PROPERTY;\n  }\n\n  init() {\n    super.init();\n\n    this.flag('visibleFlag', true);\n    this.message = 'Expected element %s to ' + (this.negate ? 'not be visible' : 'be visible');\n    this.start();\n  }\n\n  executeCommand() {\n    return this.executeProtocolAction('isElementDisplayed');\n  }\n\n  onResultSuccess() {\n    this.passed = this.negate ? this.resultValue === false : !!this.resultValue;\n    this.expected = this.negate ? 'not visible' : 'visible';\n    this.actual = this.getActual();\n\n    this.addExpectedInMessagePart();\n  }\n\n  onResultFailed() {\n    this.passed = false;\n    this.expected = this.negate ? 'not visible' : 'visible';\n    this.actual = 'not found';\n  }\n\n  getActual() {\n    const value = this.resultValue === true ? 'visible' : 'not visible';\n\n    return super.getActual(value);\n  }\n}\n\n\nmodule.exports = VisibleAssertion;\n"
  },
  {
    "path": "lib/api/expect/assertions/elements/count.js",
    "content": "/**\n * Checks if the number of elements specified by a selector is equal or not to a given value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.elements('div').count.to.equal(10);\n *   browser.expect.elements('p').count.to.not.equal(1);\n * }\n *\n * @method count\n * @display .elements(<element>).count\n * @since v1.1\n * @api expect.elements\n */\nconst BaseAssertion = require('../_baseAssertion.js');\n\nclass CountAssertion extends BaseAssertion {\n  static get assertionName() {\n    return ['count'];\n  }\n\n  static get assertionType() {\n    return BaseAssertion.AssertionType.PROPERTY;\n  }\n\n  init() {\n    super.init();\n\n    this.flag('valueFlag', true);\n    this.start();\n    const selector = this.element && this.element.selector ? this.element.selector : '...';\n    this.message = `Expected elements <${selector}> count to`;\n  }\n\n  executeCommand() {\n    this.message = `Expected elements <${this.element.selector}> count to`;\n    const {length} = this.emitter.resultValue;\n\n    this.actual = length;\n\n    return Promise.resolve({\n      value: length\n    });\n  }\n\n  getActual(actual) {\n    if (this.actual === undefined) {\n      return super.getActual(actual);\n    }\n\n    return this.actual;\n  }\n\n  onResultSuccess() {\n    if (this.retries > 0 && this.negate) {\n      return;\n    }\n\n    this.addExpectedInMessagePart();\n  }\n\n  onResultFailed() {\n    this.passed = false;\n  }\n}\n\nmodule.exports = CountAssertion;\n"
  },
  {
    "path": "lib/api/expect/component.js",
    "content": "const ExpectElement = require('./element.js');\n\nclass ExpectComponent extends ExpectElement {\n  constructor(...args) {\n    super(...args);\n\n    this.flag('component', true);\n  }\n}\n\nmodule.exports = ExpectComponent;\n"
  },
  {
    "path": "lib/api/expect/cookie.js",
    "content": "/**\n * Checks if the content of the title element is of an expected value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.cookie('cookie-name').to.contain('cookie-value');\n *   browser.expect.cookie('cookie-name').to.match(/regex/);\n *   browser.expect.cookie('loginCookie', 'example.org').to.contain('cookie-value');\n * }\n *\n * @method cookie\n * @display .expect.cookie()\n * @param {string} name The name of the cookie to be inspected\n * @param {string} domain The domain name for which the cookie is set.\n * @since v1.1\n * @api expect\n */\nconst BaseExpect = require('./_baseExpect.js');\n\nclass ExpectCookie extends BaseExpect {\n  get needsFlags() {\n    return ['contains', 'startsWith', 'endsWith', 'matches', 'equal'];\n  }\n\n  get hasAssertions() {\n    return false;\n  }\n\n  getMessage(negate) {\n    this.cookieName = this.commandArgs[0] || '';\n    this.cookieDomain = this.commandArgs[1] || '';\n\n    let {cookieName = '', cookieDomain} = this;\n    cookieName = `\"${cookieName}\"`;\n\n    if (cookieDomain) {\n      cookieName += ` for domain \"${cookieDomain}\"`;\n    }\n\n    return `Expected cookie ${cookieName} to${negate ? ' not' : ''}`;\n  }\n\n  command(...args) {\n    return this.transportActions.getCookie(...args);\n  }\n\n  handleCommandPromise(promise) {\n    promise\n      .then((result) => {\n        const domainStr = this.cookieDomain ? ` for domain \"${this.cookieDomain}\"` : '';\n        if (!result.value) {\n          return this.reject(new NotFoundError(`no cookie \"${this.cookieName}\"${domainStr} was found`));\n        }\n\n        if (result && result.value) {\n          if (Array.isArray(result.value)) {\n            this.resultValue = result.value.length > 0 ? result.value[0].value : null;\n          } else {\n            // result.value represents the cookie object, so result.value.value would be the cookie value\n            this.resultValue = result.value.value;\n          }\n        } else {\n          this.resultValue = {};\n        }\n\n        return this.resolve(this.resultValue);\n      })\n      .catch((result) => {\n        this.reject(result);\n      });\n  }\n}\n\nclass NotFoundError extends Error {\n  constructor(props) {\n    super(props);\n    this.name = 'NotFoundError';\n  }\n}\n\nmodule.exports = ExpectCookie;\n"
  },
  {
    "path": "lib/api/expect/element.js",
    "content": "const {By} = require('selenium-webdriver');\nconst Element = require('../../element');\nconst BaseExpect = require('./_baseExpect.js');\n\nclass ExpectElement extends BaseExpect {\n  get needsFlags() {\n    return [\n      'value',\n      'active',\n      'attribute',\n      'css',\n      'enabled',\n      'present',\n      'selected',\n      'text',\n      'type',\n      'visible'\n    ];\n  }\n\n  get hasAssertions() {\n    return true;\n  }\n\n  get promiseRejectedMsg() {\n    return 'Element was not found.';\n  }\n\n  /**\n   * If this is missing, it will be the main expect command name\n   * @return {string}\n   */\n  get assertionsPath() {\n    return './element';\n  }\n\n  /**\n   * @param [args]\n   * @return {Promise}\n   */\n  command(...args) {\n    this.createElement(...args);\n\n    return this.locateElement();\n  }\n\n  getComponentProperty(property) {\n    return this.client.transportActions.executeScript(function(property) {\n      // eslint-disable-next-line\n      if (!window['@@component_element']) {\n        throw new Error('Component was not rendered.');\n      }\n      // eslint-disable-next-line\n      return window['@@component_element'].componentVM[property];\n    }, [property]);\n  }\n\n  retryCommand() {\n    const promise = this.locateElement();\n    this.handleCommandPromise(promise);\n  }\n\n  createElement(selector, using = this.client.locateStrategy) {\n    let value = selector;\n    if (selector.webElementLocator instanceof By) {\n      const {webElementLocator} = selector;\n      value = webElementLocator.value;\n      using = webElementLocator.using;\n    }\n\n    this.element = Element.createFromSelector(value, using);\n    this.flag('element', this.element);\n\n    return this;\n  }\n\n  locateElement() {\n    const {element} = this;\n\n    return this.elementLocator\n      .findElement({element, cacheElementId: false})\n      .then(elementResult => {\n        if (elementResult && elementResult.value) {\n          this.elementId = this.transport.getElementId(elementResult.value);\n\n          return elementResult;\n        }\n\n        const {error} = elementResult;\n        if (error instanceof Error) {\n          throw error;\n        }\n\n        throw elementResult;\n      });\n  }\n}\n\nmodule.exports = ExpectElement;\n"
  },
  {
    "path": "lib/api/expect/elements.js",
    "content": "const Element = require('../../element');\nconst BaseExpect = require('./_baseExpect.js');\n\nclass ExpectElements extends BaseExpect {\n  get needsFlags() {\n    return ['value'];\n  }\n\n  get hasAssertions() {\n    return true;\n  }\n\n  get promiseRejectedMsg() {\n    return 'Element was not found.';\n  }\n\n  /**\n   * If this is missing, it will be the main expect command name\n   * @return {string}\n   */\n  get assertionsPath() {\n    return './elements';\n  }\n\n  constructor(opts) {\n    super(opts);\n\n    if (this.commandArgs[0] instanceof Promise) {\n      return;\n    }\n\n    this.createElement(...this.commandArgs);\n  }\n\n  async command(...args) {\n    if (!this.element && (this.commandArgs[0] instanceof Promise)) {\n      const value = await this.commandArgs[0];\n      this.element = {\n        value,\n        selector: 'elements'\n      };\n\n      this.flag('element', this.element);\n      this.resultValue = value;\n      this.retryUnavailable = true; //retry is not possible in this case\n\n      return this.resolve(value);\n    }\n\n    return this.locateElements();\n  }\n\n  locateElements() {\n    const {element} = this;\n\n    return this.elementLocator\n      .findElement({element, returnSingleElement: false, cacheElementId: false})\n      .then(result => {\n        const {value, error} = result;\n\n        let elements;\n        if (value) {\n          elements = this.transport.mapWebElementIds(value);\n        } else if (error instanceof Error && error.name === 'NoSuchElementError') {\n          elements = this.transport.mapWebElementIds([]);\n        } else {\n          throw result;\n        }\n\n        this.resultValue = elements;\n\n        return this.resolve(elements);\n      });\n  }\n\n  retryCommand() {\n    const promise = this.locateElements();\n    this.handleCommandPromise(promise);\n  }\n\n  createElement(selector, using = this.client.locateStrategy) {\n    this.element = Element.createFromSelector(selector, using);\n    this.flag('element', this.element);\n\n    return this;\n  }\n\n}\n\nmodule.exports = ExpectElements;\n"
  },
  {
    "path": "lib/api/expect/title.js",
    "content": "/**\n * Checks if the content of the page title is of an expected value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.title().to.contain('value');\n *   browser.expect.title().to.match(/value/);\n * }\n *\n * @method title\n * @display .title()\n * @since v1.1\n * @api expect\n */\nconst BaseExpect = require('./_baseExpect.js');\n\nclass ExpectTitle extends BaseExpect {\n  get needsFlags() {\n    return [\n      'contains',\n      'startsWith',\n      'endsWith',\n      'matches',\n      'equal'\n    ];\n  }\n\n  get assertionType() {\n    return 'property';\n  }\n\n  get hasAssertions() {\n    return false;\n  }\n\n  getMessage(negate) {\n    return `Expected page title to${negate ? ' not' : ''}`;\n  }\n\n  command() {\n    return this.transportActions.getPageTitle();\n  }\n}\n\nmodule.exports = ExpectTitle;\n"
  },
  {
    "path": "lib/api/expect/url.js",
    "content": "/**\n * Checks if the page url is of an expected value.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.expect.url().to.contain('https://');\n *   browser.expect.url().to.endWith('.org');\n * }\n *\n * @method url\n * @display .url()\n * @since v1.1\n * @api expect\n */\nconst BaseExpect = require('./_baseExpect.js');\n\nclass ExpectUrl extends BaseExpect {\n  get needsFlags() {\n    return [\n      'contains',\n      'startsWith',\n      'endsWith',\n      'matches',\n      'equal'\n    ];\n  }\n\n  get assertionType() {\n    return 'method';\n  }\n\n  get hasAssertions() {\n    return false;\n  }\n\n  getMessage(negate) {\n    return `Expected current url to${negate ? ' not' : ''}`;\n  }\n\n  command() {\n    return this.transportActions.getCurrentUrl();\n  }\n}\n\nmodule.exports = ExpectUrl;\n"
  },
  {
    "path": "lib/api/index.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst Utils = require('../utils');\nconst StaticApis = require('./_loaders/static.js');\nconst CommandLoader = require('./_loaders/command.js');\nconst ElementCommandLoader = require('./_loaders/element-command.js');\nconst AssertionLoader = require('./_loaders/assertion.js');\nconst ExpectLoader = require('./_loaders/expect.js');\nconst PageObjectLoader = require('./_loaders/page-object.js');\nconst WithinContextLoader = require('./_loaders/within-context.js');\nconst PluginLoader = require('./_loaders/plugin.js');\n\nconst __elementCommandsStrict = [];\nconst __elementCommands = [];\nconst DEFAULT_PLUGINS = ['nightwatch-axe-verbose'];\n\nclass ApiLoader {\n  static isElementCommand(commandName) {\n    return __elementCommands.includes(commandName);\n  }\n\n  static get CommandFiles() {\n    return {\n      protocolActions: {\n        dirPath: 'protocol',\n        protocol: true\n      },\n      clientCommands: 'client-commands',\n\n      elementCommands: {\n        dirPath: 'element-commands',\n        element: true,\n        loader: ElementCommandLoader\n      },\n\n      assertions: {\n        loader: AssertionLoader,\n        dirPath: 'assertions',\n        element: true,\n        namespaces: {\n          assert: {\n            abortOnFailure: true\n          },\n          verify: {\n            abortOnFailure: false\n          }\n        }\n      },\n\n      expect: {\n        loader: ExpectLoader,\n        dirPath: 'expect',\n        element: true,\n        namespaces: {\n          expect: {\n            abortOnFailure: true\n          },\n          should: {\n            abortOnFailure: false\n          }\n        }\n      }\n    };\n  }\n\n  /**\n   * @param {*} customPath\n   * @return {Array}\n   */\n  static adaptCustomPath(customPath) {\n    return customPath.map(location => {\n      return path.resolve(location);\n    });\n  }\n\n  static getElementsCommandsStrict() {\n    return __elementCommandsStrict;\n  }\n\n  static init(nightwatchInstance) {\n    const api = new ApiLoader(nightwatchInstance);\n    const staticApis = new StaticApis(nightwatchInstance);\n    staticApis.loadStaticAssertions();\n    staticApis.loadStaticExpect();\n\n    api.loadApiCommandsSync();\n\n    return WithinContextLoader.loadCommandCache(nightwatchInstance)\n      .then(_ => api.loadCustomCommands())\n      .then(_ => api.loadCustomAssertions())\n      .then(_ => api.initPluginTransforms())\n      .then(_ => api.loadPlugins())\n      .then(_ => api.defineWithinContext())\n      .then(_ => api.loadPageObjects())\n      .then(_ => {\n        if (!nightwatchInstance.unitTestingMode) {\n          const EnsureApi = require('./_loaders/ensure.js');\n          const ensureApi = new EnsureApi(nightwatchInstance);\n          ensureApi.loadAssertions();\n\n          const ChromeApi = require('./_loaders/chrome.js');\n          const chromeApis = new ChromeApi(nightwatchInstance);\n          chromeApis.loadCommands();\n\n          const FirefoxApi = require('./_loaders/firefox.js');\n          const firefoxApis = new FirefoxApi(nightwatchInstance);\n          firefoxApis.loadCommands();\n        }\n      });\n  }\n\n  constructor(nightwatchInstance) {\n    this.nightwatchInstance = nightwatchInstance;\n  }\n\n  get api() {\n    return this.nightwatchInstance.api;\n  }\n\n  get reporter() {\n    return this.nightwatchInstance.reporter;\n  }\n\n  get settings() {\n    return this.nightwatchInstance.settings;\n  }\n\n  get commandQueue() {\n    return this.nightwatchInstance.queue;\n  }\n\n  static makeAssertProxy(api) {\n    return new Proxy(api, {\n      get(target, name) {\n        if (name === '__isProxy') {\n          return true;\n        }\n\n        if (name === 'not') {\n          return new Proxy(api, {\n            get(target, name) {\n              return function (...args) {\n                if (!Utils.isFunction(target[name])) {\n                  throw new Error(`Unknown api method .not.\"${name}\".`);\n                }\n\n                return target[name]({negate: true, args});\n              };\n            }\n          });\n        }\n\n        return function (...args) {\n          if (typeof name != 'string') {\n            return null;\n          }\n          if (!Utils.isFunction(target[name])) {\n            throw new Error(`Unknown api method \"${name}\".`);\n          }\n\n          return target[name]({negate: false, args});\n        };\n      }\n    });\n  }\n\n\n  initPluginTransforms() {\n    this.nightwatchInstance.transforms = Promise.resolve([]);\n\n    return Promise.resolve();\n  }\n\n  loadPlugins(parent = null) {\n    let plugins = DEFAULT_PLUGINS.concat(this.nightwatchInstance.options.plugins || []);\n    plugins = [... new Set(plugins)];\n\n    const promises = [];\n    plugins.forEach(pluginName => {\n      const plugin = PluginLoader.load(pluginName);\n\n      if (plugin.commands) {\n        promises.push(this.__loadCustomObjects({\n          parent,\n          sourcePath: plugin.commands,\n          isUserDefined: true\n        }));\n      }\n\n      if (plugin.assertions) {\n        promises.push(this.__loadCustomObjects({\n          parent,\n          sourcePath: plugin.assertions,\n          namespaces: ApiLoader.CommandFiles.assertions.namespaces,\n          Loader: AssertionLoader\n        }));\n      }\n\n      if (plugin.transforms) {\n        promises.push(Promise.resolve(this.__loadPluginTransforms(plugin.transforms)));\n      }\n    });\n\n    return Promise.all(promises);\n  }\n\n\n  async defineWithinContext(parent) {\n    const loader = new WithinContextLoader(this.nightwatchInstance);\n    loader.define(parent);\n\n    return Promise.resolve();\n  }\n\n  /**\n   * Loads the page objects, if defined\n   * @param parent\n   */\n  async loadPageObjects(parent = null) {\n    await PageObjectLoader.loadApiCommands(this.nightwatchInstance);\n\n    return this.__loadCustomObjects({\n      parent,\n      sourcePath: this.nightwatchInstance.options.page_objects_path,\n      isUserDefined: true,\n      Loader: PageObjectLoader\n    });\n  }\n\n  /**\n   * Loads custom assertions, if defined\n   *\n   * @param parent\n   */\n  loadCustomAssertions(parent = null) {\n    return this.__loadCustomObjects({\n      parent,\n      sourcePath: this.nightwatchInstance.options.custom_assertions_path,\n      namespaces: ApiLoader.CommandFiles.assertions.namespaces,\n      Loader: AssertionLoader\n    });\n  }\n\n  /**\n   * Loads custom commands, if defined\n   * @param parent\n   */\n  loadCustomCommands(parent = null) {\n    return this.__loadCustomObjects({\n      parent,\n      sourcePath: this.nightwatchInstance.options.custom_commands_path,\n      isUserDefined: true\n    });\n  }\n\n  /**\n   * Loads built-in api commands, assertions, and expect definitions\n   * @param parent\n   * @param {object} options\n   */\n  loadApiCommandsSync(parent = null, {loadAssertions = true, loadClientCommands = true} = {}) {\n    Object.keys(ApiLoader.CommandFiles)\n      .forEach((key) => {\n        const commands = ApiLoader.CommandFiles[key];\n        const {namespaces} = commands;\n\n        if (!loadAssertions && key === 'assertions') {\n          return;\n        }\n\n        if (!loadClientCommands && key === 'clientCommands') {\n          return;\n        }\n\n        let elementCommandStrict = false;\n        if (key === 'elementCommands') {\n          elementCommandStrict = true;\n        }\n\n        let dirPath;\n        let Loader = CommandLoader;\n        let isProtocolCommand = false;\n        let isElementCommand = false;\n\n        if (Utils.isString(commands)) {\n          dirPath = path.join(__dirname, commands);\n        } else {\n          dirPath = path.join(__dirname, commands.dirPath);\n          isProtocolCommand = commands.protocol;\n          isElementCommand = commands.element;\n\n          if (commands.loader) {\n            Loader = commands.loader;\n          }\n        }\n\n        const opts = {\n          dirPath,\n          parent,\n          Loader,\n          isProtocolCommand,\n          isElementCommand,\n          elementCommandStrict,\n          namespacesObj: namespaces\n        };\n\n        // protocol commands are not loaded onto the main page object\n        if (parent && isProtocolCommand) {\n          return;\n        }\n\n        this.__loadCommandsSync(opts);\n      });\n  }\n\n  addCommandDefinitionSync({\n    dirPath,\n    isUserDefined = false,\n    fileName,\n    parent,\n    namespace = [],\n    abortOnFailure = false,\n    isProtocolCommand = false,\n    isElementCommand = false,\n    elementCommandStrict = false,\n    Loader = CommandLoader\n  }) {\n    const loader = new Loader(this.nightwatchInstance);\n    loader.isUserDefined = isUserDefined;\n\n    if (namespace && namespace.length) {\n      loader.setNamespace(namespace);\n    }\n\n    loader\n      .loadModule(dirPath, fileName)\n      .createWrapper(abortOnFailure)\n      .define(parent);\n\n    if (isElementCommand && loader.commandName && !__elementCommands.includes(loader.commandName)) {\n      __elementCommands.push(loader.commandName);\n    }\n\n    if (elementCommandStrict && loader.commandName && !__elementCommandsStrict.includes(loader.commandName)) {\n      __elementCommandsStrict.push(loader.commandName);\n    }\n  }\n\n  async addCommandDefinitionAsync({\n    dirPath,\n    isUserDefined = false,\n    fileName,\n    parent,\n    namespace = [],\n    abortOnFailure = false,\n    isElementCommand = false,\n    Loader = CommandLoader\n  }) {\n    const loader = new Loader(this.nightwatchInstance);\n    loader.isUserDefined = isUserDefined;\n\n    if (namespace && namespace.length) {\n      loader.setNamespace(namespace);\n    }\n\n    await loader.loadModuleAsync(dirPath, fileName);\n    loader.createWrapper(abortOnFailure).define(parent);\n\n    if (isElementCommand && loader.commandName && !__elementCommands.includes(loader.commandName)) {\n      __elementCommands.push(loader.commandName);\n    }\n  }\n\n  __loadCustomObjects({parent = null, Loader = CommandLoader, namespaces, sourcePath}) {\n    if (!sourcePath) {\n      sourcePath = [];\n    }\n\n    if (!Array.isArray(sourcePath)) {\n      sourcePath = [sourcePath];\n    }\n\n    const dirPathArr = ApiLoader.adaptCustomPath(sourcePath);\n    const commandFiles = [];\n\n    dirPathArr.forEach((dirPath, index) => this.__loadCommandsSync({\n      parent,\n      dirPath,\n      originalSourcePath: sourcePath[index],\n      isUserDefined: true,\n      namespacesObj: namespaces,\n      Loader,\n      loadAction(opts) {\n        commandFiles.push(opts);\n      }\n    }));\n\n    const hasCorrespondingJsFile = (parsedResource) => {\n      const jsFile = path.join(parsedResource.dir, `${parsedResource.name}${Utils.jsFileExt}`);\n\n      const entry = commandFiles.find(({dirPath, fileName}) => {\n        return path.join(dirPath, fileName) === jsFile;\n      });\n\n      return !!entry;\n    };\n\n    const commandFilesProcessed = commandFiles.reduce((prev, opts) => {\n      const {dirPath, fileName} = opts;\n      const fullPath = path.join(dirPath, fileName);\n      const parsedResource = path.parse(fullPath);\n      const isTypeScriptFile = parsedResource.ext === Utils.tsFileExt;\n\n      // ignore `.ts` files if a `.js` has already been loaded\n      if (isTypeScriptFile && hasCorrespondingJsFile(parsedResource)) {\n        return prev;\n      }\n\n      prev.push(opts);\n\n      return prev;\n    }, []);\n\n    return Promise.all(commandFilesProcessed.map(opts => this.addCommandDefinitionAsync(opts)));\n    //commandFilesProcessed.forEach(opts => this.addCommandDefinitionSync(opts));\n  }\n\n  __loadCommandsSync({\n    parent = null,\n    namespacesObj = null,\n    ns = null,\n    dirPath,\n    originalSourcePath,\n    abortOnFailure = false,\n    isProtocolCommand = false,\n    isElementCommand = false,\n    isUserDefined = false,\n    elementCommandStrict = false,\n    Loader = CommandLoader,\n    loadAction = this.addCommandDefinitionSync.bind(this)\n  }) {\n    if (namespacesObj) {\n      Object.keys(namespacesObj).forEach((ns) => this.__loadCommandsSync({\n        ns,\n        parent,\n        dirPath,\n        isUserDefined,\n        isElementCommand,\n        elementCommandStrict,\n        Loader,\n        loadAction: isUserDefined ? loadAction : this.addCommandDefinitionSync.bind(this),\n        abortOnFailure: namespacesObj[ns].abortOnFailure\n      }));\n    } else {\n      Utils.readFolderRecursively(dirPath, [], (dirPath, fileName, namespace) => {\n        loadAction.call(this, {\n          dirPath,\n          fileName,\n          parent,\n          isUserDefined,\n          namespace: ns || namespace,\n          isProtocolCommand,\n          isElementCommand,\n          elementCommandStrict,\n          Loader,\n          abortOnFailure\n        });\n      }, function readDirFn(sourcePath) {\n        try {\n          return {\n            resources: fs.readdirSync(sourcePath),\n            sourcePath\n          };\n        } catch (err) {\n          if (err.code === 'ENOENT' && originalSourcePath && originalSourcePath.startsWith('examples/')) {\n            return readDirFn(path.join('node_modules/nightwatch/', originalSourcePath));\n          }\n\n          throw err;\n        }\n\n      });\n    }\n  }\n\n  __loadCommands({\n    parent = null,\n    namespacesObj = null,\n    ns = null,\n    dirPath,\n    abortOnFailure = false,\n    isProtocolCommand = false,\n    isElementCommand = false,\n    isUserDefined = false,\n    Loader = CommandLoader,\n    loadAction = this.addCommandDefinitionAsync.bind(this)\n  }) {\n    if (namespacesObj) {\n      return Promise.all(Object.keys(namespacesObj).map((ns) => {\n        return this.__loadCommands({\n          ns,\n          parent,\n          dirPath,\n          isUserDefined,\n          isElementCommand,\n          Loader,\n          abortOnFailure: namespacesObj[ns].abortOnFailure\n        });\n      }));\n    }\n\n    const promises = [];\n\n    Utils.readFolderRecursively(dirPath, [], (dirPath, fileName, namespace) => {\n      const result = Promise.resolve(loadAction.call(this, {\n        dirPath,\n        fileName,\n        parent,\n        isUserDefined,\n        namespace: ns || namespace,\n        isProtocolCommand,\n        isElementCommand,\n        Loader,\n        abortOnFailure\n      }));\n\n      promises.push(result);\n\n    }, function readDirFn(sourcePath) {\n      return {\n        resources: fs.readdirSync(sourcePath),\n        sourcePath\n      };\n    });\n\n    return Promise.all(promises);\n  }\n\n  /**\n   * @param {function|Array} transforms\n   * @returns {Promise}\n   */\n  __normalizeTransforms(transforms) {\n    if (typeof transforms === 'function') {\n      return transforms();\n    }\n\n    return Promise.resolve(transforms || []);\n  }\n\n  /**\n   * @param {function|Array} nextTransforms\n   */\n  __loadPluginTransforms(nextTransforms) {\n    this.nightwatchInstance.transforms = this.nightwatchInstance.transforms.then(existingTransforms =>\n      this.__normalizeTransforms(nextTransforms).then(items => existingTransforms.concat(items)));\n  }\n}\n\nmodule.exports = ApiLoader;\n"
  },
  {
    "path": "lib/api/protocol/_base-action.js",
    "content": "const Element = require('../../element');\nconst {isFunction, isString, makePromise} = require('../../utils');\nconst {By} = require('selenium-webdriver');\nconst {LocateStrategy} = Element;\n\nmodule.exports = class ProtocolAction {\n  static get ScreenOrientation() {\n    return ['LANDSCAPE', 'PORTRAIT'];\n  }\n\n  static get MouseButton() {\n    return {\n      LEFT: 'left',\n      MIDDLE: 'middle',\n      RIGHT: 'right'\n    };\n  }\n\n  static validateElementId(id, apiMethod) {\n    if (!isString(id)) {\n      const err = new Error(`First argument passed to .${apiMethod}() should be a web element ID string. Received ${typeof id}.`);\n      err.detailedErr = `See https://nightwatchjs.org/api/${apiMethod}.html\\n`;\n      throw err;\n    }\n  }\n\n  static get elementCommandToActionMap() {\n    return {\n      element: {\n        transportAction: 'locateSingleElement',\n        returnSingleElement: true\n      },\n      elements: {\n        transportAction: 'locateMultipleElements',\n        returnSingleElement: false\n      },\n      elementIdElement: {\n        transportAction: 'locateSingleElementByElementId',\n        returnSingleElement: true\n      },\n      elementIdElements: {\n        transportAction: 'locateMultipleElementsByElementId',\n        returnSingleElement: false\n      },\n      findElement: {\n        transportAction: 'locateMultipleElements',\n        returnSingleElement: true\n      },\n      findElements: {\n        transportAction: 'locateMultipleElements',\n        returnSingleElement: false\n      }\n    };\n  }\n\n  reportProtocolErrors(result) {\n    return !(result && (result.error instanceof Error) && result.error.registered);\n  }\n\n  get elementLocator() {\n    return this.client.elementLocator;\n  }\n\n  get transport() {\n    return this.client.transport;\n  }\n\n  get requiresSeleniumWebdriver() {\n    return false;\n  }\n\n  get settings() {\n    return this.client.settings;\n  }\n\n  /**\n   * @type {Nightwatch}\n   * @return {*}\n   */\n  get client() {\n    return this.__nightwatchInstance;\n  }\n\n  get api() {\n    return this.client.api;\n  }\n\n  constructor(nightwatchInstance) {\n    this.__nightwatchInstance = nightwatchInstance;\n  }\n\n  /*!\n   * @override\n   * @return {Promise}\n   */\n  async command() {}\n\n  /*!\n   *\n   * @param {Element} [element]\n   * @param {Element} [parentElement]\n   * @param {String} [id]\n   * @param {String} using\n   * @param {String} value\n   * @param {function} [callback]\n   *\n   * @return {Promise}\n   */\n  findElements({element, parentElement, id, using, value, commandName, callback = function(r) {return r}}) {\n    if (!(element instanceof Element) && !(element instanceof By)) {\n      try {\n        element = Element.createFromSelector(value, using);\n      } catch (err) {\n        return Promise.reject(err);\n      }\n    }\n\n    if ((element instanceof Element) && !element.usingRecursion) {\n      LocateStrategy.validate(element.locateStrategy, commandName);\n    }\n\n    return this.locate({id, element, parentElement, commandName})\n      .then(result => {\n        if (commandName !== 'element' && result && (result.error instanceof Error) && result.error.name === 'NoSuchElementError') {\n          result = {\n            value: [],\n            status: 0\n          };\n        }\n\n        return makePromise(callback, this.api, [result]);\n      });\n  }\n\n  /*!\n   *\n   * @param {Element} element\n   * @param {string} protocolCommand either \"elements\"(multiple) or \"element\"(single)\n   */\n  async locate({id, element, parentElement, commandName}) {\n    const {transportAction, returnSingleElement} = ProtocolAction.elementCommandToActionMap[commandName];\n\n    if ((element instanceof Element) && element.usingRecursion) {\n      return this.elementLocator.findElement({element, transportAction, returnSingleElement});\n    }\n\n    if (parentElement) {\n      const elementResponse = await this.elementLocator.findElement({element: parentElement});\n      if (!elementResponse.value) {\n        return {\n          value: null,\n          status: -1,\n          err: new Error(`No element found for ${parentElement}.`)\n        };\n      }\n\n      id = this.transport.getElementId(elementResponse.value);\n    }\n\n    return this.elementLocator.executeProtocolAction({id, element, transportAction, commandName});\n  }\n\n  /*!\n   * Helper function for mouseButton actions\n   *\n   * @param {string} handler\n   * @param {string|number} button\n   * @param {function} callback\n   * @private\n   */\n  mouseButtonHandler(handler, button, callback) {\n    let buttonIndex;\n\n    if (button === undefined && callback === undefined) {\n      button = 0;\n    } else {\n      if (isFunction(button)) {\n        callback = button;\n        button = 0;\n      }\n\n      if (isString(button)) {\n        buttonIndex = [\n          ProtocolAction.MouseButton.LEFT,\n          ProtocolAction.MouseButton.MIDDLE,\n          ProtocolAction.MouseButton.RIGHT\n        ].indexOf(button.toLowerCase());\n\n        if (buttonIndex !== -1) {\n          button = buttonIndex;\n        }\n      }\n    }\n\n    return this.transportActions[handler](button, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/acceptAlert.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Accepts the currently displayed alert dialog. Usually, this is equivalent to clicking on the 'OK' button in the dialog.\n *\n * @method acceptAlert\n * @link /#accept-alert\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @exampleLink /api/acceptAlert.js\n * @api protocol.userprompts\n * @deprecated In favour of `.alerts.accept()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.acceptAlert(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/getContext.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Get the current context in which Appium is running. Used when testing hybrid mobile apps using Appium.\n *\n * More info here: https://appium.io/docs/en/commands/context/get-context/\n *\n * @example\n * module.exports = {\n *   'get current context': function (app) {\n *     app\n *       .appium.getContext(function (result) {\n *         console.log('the current context is:', result.value);\n *       });\n *   },\n *\n *   'get current context with ES6 async/await': async function (app) {\n *     const context = await app.appium.getContext();\n *     console.log('the current context is:', context);\n *   }\n * };\n *\n * @syntax .appium.getContext([callback])\n * @method getContext\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {string|null} A string representing the current context, or `null` representing \"no context\".\n * @moreinfo appium.io/docs/en/writing-running-appium/web/hybrid/index.html\n * @see appium.setContext\n * @see appium.getContexts\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getCurrentContext(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/getContexts.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Get a list of the available contexts. Used when testing hybrid mobile apps using Appium.\n *\n * More info here: https://appium.io/docs/en/commands/context/get-contexts/\n *\n * @example\n * module.exports = {\n *   'get available contexts': function (app) {\n *     app\n *       .appium.getContexts(function (result) {\n *         console.log('the available contexts are:', result.value);\n *       });\n *   },\n *\n *   'get available contexts with ES6 async/await': async function (app) {\n *     const contexts = await app.appium.getContexts();\n *     console.log('the available contexts are:', contexts);\n *   }\n * };\n *\n * @syntax .appium.getContexts([callback])\n * @method getContexts\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {Array<string>} An array of strings representing available contexts, e.g 'WEBVIEW_<id>', or 'NATIVE_APP'\n * @moreinfo appium.io/docs/en/writing-running-appium/web/hybrid/index.html\n * @see appium.getContext\n * @see appium.setContext\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getAvailableContexts(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/getCurrentActivity.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Get the name of the current Android activity.\n *\n * @example\n * module.exports = {\n *   'get current activity name': function (app) {\n *     app\n *       .appium.getCurrentActivity(function (result) {\n *         console.log('current android activity is:', result.value);\n *       });\n *   },\n *\n *   'get current activity name with ES6 async/await': async function (app) {\n *     const activity = await app.appium.getCurrentActivity();\n *     console.log('current android activity is:', activity);\n *   }\n * };\n *\n * @syntax .appium.getCurrentActivity([callback])\n * @method getCurrentActivity\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {string} Name of the current activity.\n * @see appium.getCurrentPackage\n * @see appium.startActivity\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getCurrentActivity(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/getCurrentPackage.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Get the name of the current Android package.\n *\n * @example\n * module.exports = {\n *   'get current package name': function (app) {\n *     app\n *       .appium.getCurrentPackage(function (result) {\n *         console.log('current android package is:', result.value);\n *       });\n *   },\n *\n *   'get current package name with ES6 async/await': async function (app) {\n *     const packageName = await app.appium.getCurrentPackage();\n *     console.log('current android package is:', packageName);\n *   }\n * };\n *\n * @syntax .appium.getCurrentPackage([callback])\n * @method getCurrentPackage\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {string} Name of the current package.\n * @see appium.getCurrentActivity\n * @see appium.startActivity\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getCurrentPackage(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/getGeolocation.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Get the current geolocation of the mobile device.\n *\n * @example\n * module.exports = {\n *   'get device geolocation': function (app) {\n *     app\n *       .appium.getGeolocation(function (result) {\n *         console.log('current device geolocation is:', result.value);\n *       });\n *   },\n *\n *   'get device geolocation with ES6 async/await': async function (app) {\n *     const location = await app.appium.getGeolocation();\n *     console.log('current device geolocation is:', location);\n *   }\n * };\n *\n * @syntax .appium.getGeolocation([callback])\n * @method getGeolocation\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {object} The current geolocation: `{latitude: number, longitude: number, altitude: number}`.\n * @see appium.setGeolocation\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getDeviceGeolocation(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/getOrientation.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Get the current device orientation.\n *\n * @example\n * module.exports = {\n *   'get current device orientation': function (app) {\n *     app\n *       .appium.getOrientation(function (result) {\n *         console.log('current device orientation is:', result.value);\n *       });\n *   },\n *\n *   'get current device orientation with ES6 async/await': async function (app) {\n *     const orientation = await app.appium.getOrientation();\n *     console.log('current device orientation is:', orientation);\n *   }\n * };\n *\n * @syntax .appium.getOrientation([callback])\n * @method getOrientation\n * @param {function} callback Callback function which is called with the result value.\n * @returns {string} The current device orientation: `LANDSCAPE` or `PORTRAIT`.\n * @see appium.setOrientation\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getScreenOrientation(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/hideKeyboard.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Hide soft keyboard.\n *\n * @example\n * module.exports = {\n *   'hide device soft keyboard': function (app) {\n *     app\n *       .appium.hideKeyboard();\n *   },\n *\n *   'hide device soft keyboard with ES6 async/await': async function (app) {\n *     await app.appium.hideKeyboard();\n *   }\n * };\n *\n * @syntax .appium.hideKeyboard([callback])\n * @method hideKeyboard\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see appium.isKeyboardShown\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.hideDeviceKeyboard({}, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/isKeyboardShown.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Whether or not the soft keyboard is shown.\n *\n * @example\n * module.exports = {\n *   'whether keyboard is shown': function (app) {\n *     app\n *       .appium.isKeyboardShown(function (result) {\n *         console.log('result value of whether keyboard is shown:', result.value);\n *       });\n *   },\n *\n *   'whether keyboard is shown with ES6 async/await': async function (app) {\n *     const result = await app.appium.isKeyboardShown();\n *     console.log('result value of whether keyboard is shown:', result);\n *   }\n * };\n *\n * @syntax .appium.isKeyboardShown([callback])\n * @method isKeyboardShown\n * @param {function} [callback] Callback function which is called with the result value.\n * @returns {boolean} True if the keyboard is shown.\n * @see appium.hideKeyboard\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.isDeviceKeyboardShown(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/longPressKeyCode.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Press and hold a particular key on an Android Device.\n *\n * See [official Android Developers docs](https://developer.android.com/reference/android/view/KeyEvent.html) for reference of available Android key code values.\n *\n * @example\n * module.exports = {\n *   'long press e with caps lock on (keycode 33 and metastate 1048576)': function (app) {\n *     app\n *       .appium.longPressKeyCode(33, 1048576);\n *   },\n *\n *   'long press g (keycode 35) with ES6 async/await': async function (app) {\n *     await app.appium.longPressKeyCode(35);\n *   }\n * };\n *\n * @syntax .appium.longPressKeyCode(keycode, [callback])\n * @syntax .appium.longPressKeyCode(keycode, metastate, flags, [callback])\n * @method longPressKeyCode\n * @param {number} keycode Key code to press on the device.\n * @param {number} [metastate] Meta state to press the keycode with.\n * @param {number} [flags] Flags for the keypress.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see appium.pressKeyCode\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(keycode, ...args) {\n    let metastate;\n    let flags;\n    let callback;\n\n    if (typeof keycode !== 'number') {\n      throw new Error('The first argument to longPressKeyCode is mandatory and must be a number.');\n    }\n\n    if (typeof args[0] === 'function') {\n      callback = args[0];\n    } else {\n      [metastate, flags, callback] = args;\n    }\n\n    const opts = {\n      keycode,\n      ...(metastate && {metastate}),\n      ...(flags && {flags})\n    };\n\n    return this.transportActions.longPressDeviceKeyCode(opts, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/pressKeyCode.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Press a particular key on an Android Device.\n *\n * See [official Android Developers docs](https://developer.android.com/reference/android/view/KeyEvent.html) for reference of available Android key code values.\n *\n * @example\n * module.exports = {\n *   'press e with caps lock on (keycode 33 and metastate 1048576)': function (app) {\n *     app\n *       .appium.pressKeyCode(33, 1048576);\n *   },\n *\n *   'press g (keycode 35) with ES6 async/await': async function (app) {\n *     await app.appium.pressKeyCode(35);\n *   }\n * };\n *\n * @syntax .appium.pressKeyCode(keycode, [callback])\n * @syntax .appium.pressKeyCode(keycode, metastate, flags, [callback])\n * @method pressKeyCode\n * @param {number} keycode Key code to press on the device.\n * @param {number} [metastate] Meta state to press the keycode with.\n * @param {number} [flags] Flags for the keypress.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see appium.longPressKeyCode\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(keycode, ...args) {\n    let metastate;\n    let flags;\n    let callback;\n\n    if (typeof keycode !== 'number') {\n      throw new Error('The first argument to pressKeyCode is mandatory and must be a number.');\n    }\n\n    if (typeof args[0] === 'function') {\n      callback = args[0];\n    } else {\n      [metastate, flags, callback] = args;\n    }\n\n    const opts = {\n      keycode,\n      ...(metastate && {metastate}),\n      ...(flags && {flags})\n    };\n\n    return this.transportActions.pressDeviceKeyCode(opts, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/resetApp.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Reset the app during the test.\n *\n * More info here: https://appium.io/docs/en/2.3/commands/base-driver/#reset\n *\n * @example\n * module.exports = {\n *   'reset the app': function (app) {\n *     app\n *       .appium.resetApp();\n *   },\n * };\n *\n * @syntax .appium.resetApp([callback])\n * @method resetApp\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.resetApp(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/setContext.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Set the context to be automated. Used when testing hybrid mobile apps using Appium.\n *\n * More info here: https://appium.io/docs/en/commands/context/set-context/\n *\n * @example\n * module.exports = {\n *   'switch to webview context': async function (app) {\n *     app\n *       .waitUntil(async function() {\n *         // wait for webview context to be available\n *         // initially, this.getContexts() only returns ['NATIVE_APP']\n *         const contexts = await this.appium.getContexts();\n *\n *         return contexts.length > 1;\n *       })\n *       .perform(async function() {\n *         // switch to webview context\n *         const contexts = await this.appium.getContexts();  // contexts: ['NATIVE_APP', 'WEBVIEW_<id>']\n *         await this.appium.setContext(contexts[1]);\n *       });\n *   },\n *\n *   'switch to native context': function (app) {\n *     app.appium.setContext('NATIVE_APP');\n *   }\n * };\n *\n * @syntax .appium.setContext(context, [callback])\n * @method setContext\n * @param {string} context context name to switch to - a string representing an available context.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @moreinfo appium.io/docs/en/writing-running-appium/web/hybrid/index.html\n * @see appium.getContext\n * @see appium.getContexts\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(context, callback) {\n    return this.transportActions.setCurrentContext(context, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/setGeolocation.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Set the current geolocation of the mobile device.\n *\n * @example\n * module.exports = {\n *   'set geolocation to Tokyo, Japan': function (app) {\n *     app\n *       .appium.setGeolocation({latitude: 35.689487, longitude: 139.691706, altitude: 5});\n *   },\n *\n *   'set geolocation to Tokyo, Japan with ES6 async/await': async function (app) {\n *     await app.appium.setGeolocation({latitude: 35.689487, longitude: 139.691706});\n *   }\n * };\n *\n * @syntax .appium.setGeolocation({latitude, longitude, altitude}, [callback])\n * @method setGeolocation\n * @param {object} [coordinates] `latitude` and `longitude` are required; `altitude` is optional. All should be of type `number`.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see appium.getGeolocation\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(coordinates = {}, callback) {\n    if (!('latitude' in coordinates && 'longitude' in coordinates)) {\n      throw new Error('Please provide both latitude and longitude while using setGeolocation.');\n    }\n\n    return this.transportActions.setDeviceGeolocation(coordinates, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/setOrientation.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Set the current device orientation.\n *\n * @example\n * module.exports = {\n *   'set orientation to LANDSCAPE': function (app) {\n *     app\n *       .appium.setOrientation('LANDSCAPE');\n *   },\n *\n *   'set orientation to PORTRAIT with ES6 async/await': async function (app) {\n *     await app.appium.setOrientation('PORTRAIT');\n *   }\n * };\n *\n * @syntax .appium.setOrientation(orientation, [callback])\n * @method setOrientation\n * @param {string} orientation The new device orientation: `LANDSCAPE` or `PORTRAIT`.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see appium.getOrientation\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(orientation, callback) {\n    orientation = orientation.toUpperCase();\n\n    if (!ProtocolAction.ScreenOrientation.includes(orientation)) {\n      throw new Error('Invalid screen orientation value specified. Accepted values are: ' + ProtocolAction.ScreenOrientation.join(', '));\n    }\n\n    return this.transportActions.setScreenOrientation(orientation, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/appium/startActivity.js",
    "content": "const ProtocolAction = require('../_base-action.js');\n\n/**\n * Start an Android activity by providing package name, activity name and other optional parameters.\n *\n * More info here: https://appium.io/docs/en/commands/device/activity/start-activity/\n *\n * @example\n * module.exports = {\n *   'start an android activity': function (app) {\n *     app\n *       .appium.startActivity({\n *         appPackage: 'com.android.chrome',\n *         appActivity: 'com.google.android.apps.chrome.Main'\n *       });\n *   },\n *\n *   'start the main Android activity and wait for onboarding activity to start': function (app) {\n *     app\n *       .appium.startActivity({\n *         appPackage: 'org.wikipedia',\n *         appActivity: 'org.wikipedia.main.MainActivity',\n *         appWaitActivity: 'org.wikipedia.onboarding.InitialOnboardingActivity'\n *       });\n *   }\n * };\n *\n * @syntax .appium.startActivity(opts, [callback])\n * @method startActivity\n * @param {string} opts Options to start the activity with. `appPackage` and `appActivity` are required, [others](https://appium.io/docs/en/commands/device/activity/start-activity/#json-parameters) are optional.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see appium.getCurrentActivity\n * @see appium.getCurrentPackage\n * @api protocol.appium\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(opts = {}, callback) {\n    if (!('appPackage' in opts && 'appActivity' in opts)) {\n      throw new Error('Please provide both appPackage and appActivity options while using startActivity.');\n    }\n\n    return this.transportActions.startActivity(opts, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/back.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Navigate backwards in the browser history, if possible (the equivalent of hitting the browser back button).\n *\n * @method back\n * @link /#back\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.navigation\n */\nmodule.exports = class Action extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.navigateBack(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/closeWindow.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Close the current window. This can be useful when you're working with multiple windows open (e.g. an OAuth login).\n *\n * @link /#close-window\n * @syntax .closeWindow([callback])\n * @exampleLink /api/closeWindow.js\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.window\n * @deprecated In favour of `.window.close()`.\n */\nmodule.exports = class Action extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.closeWindow(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/contexts.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Get a list of the available contexts.\n *\n * Used by Appium when testing hybrid mobile web apps. More info here: https://appium.readthedocs.io/en/latest/en/commands/context/get-contexts/\n *\n * @method contexts\n * @param {function} callback Callback function to be called when the command finishes.\n * @returns {Array} an array of strings representing available contexts, e.g 'WEBVIEW', or 'NATIVE'\n * @api protocol.mobile\n * @deprecated In favour of `.appium.getContexts()`\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getAvailableContexts(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/cookie.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Retrieve or delete all cookies visible to the current page or set a cookie. Normally this shouldn't be used directly, instead the cookie convenience methods should be used: <code>getCookie</code>, <code>getCookies</code>, <code>setCookie</code>, <code>deleteCookie</code>, <code>deleteCookies</code>.\n *\n * @link /#cookies\n * @param {string} method Http method\n * @param {function|object} [callbackOrCookie] Optional callback function to be called when the command finishes.\n * @see getCookies\n * @see getCookie\n * @see setCookie\n * @see deleteCookie\n * @see deleteCookies\n * @api protocol.cookies\n * @deprecated\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(method, callbackOrCookie) {\n    switch (method) {\n      case 'GET':\n        return this.transportActions.getCookies(callbackOrCookie);\n\n      case 'POST':\n        if (arguments.length < 2) {\n          throw new Error('POST requests to /cookie must include a cookie object parameter also.');\n        }\n\n        return this.transportActions.addCookie(callbackOrCookie, arguments[2]);\n\n      case 'DELETE':\n        if (typeof callbackOrCookie === 'undefined' || typeof callbackOrCookie === 'function') {\n          return this.transportActions.deleteAllCookies(callbackOrCookie);\n        }\n\n        return this.transportActions.deleteCookie(callbackOrCookie, arguments[2]);\n\n      default:\n        throw new Error('This method expects first argument to be either GET, POST or DELETE.');\n    }\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/currentContext.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Get current context.\n *\n * @param {function} callback Callback function to be called when the command finishes.\n * @returns {string|null} a string representing the current context or `null`, representing \"no context\"\n * @api protocol.mobile\n * @deprecated In favour of `.appium.getContext()`\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getCurrentContext(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/dismissAlert.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Dismisses the currently displayed alert dialog. For confirm() and prompt() dialogs, this is equivalent to clicking the 'Cancel' button.\n *\n * For alert() dialogs, this is equivalent to clicking the 'OK' button.\n *\n * @link /#dismiss-alert\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.userprompts\n * @deprecated In favour of `.alerts.dismiss()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.dismissAlert(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/element.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Search for an element on the page, starting from the document root. The located element will be returned as a web element JSON object.\n * First argument to be passed is the locator strategy, which is detailed on the [WebDriver docs](https://www.w3.org/TR/webdriver/#locator-strategies).\n *\n * The locator strategy can be one of:\n * - `css selector`\n * - `link text`\n * - `partial link text`\n * - `tag name`\n * - `xpath`\n *\n * @example\n * module.exports = {\n *  'demo Test' : function(browser) {\n *     browser.element('css selector', 'body', function(result) {\n *       console.log(result.value)\n *     });\n *   },\n *\n *   'es6 async demo Test': async function(browser) {\n *     const result = await browser.element('css selector', 'body');\n *     console.log('result value is:', result.value);\n *   }\n * }\n *\n * // Example with using page object elements\n * module.exports = {\n *  'demo Test with page object' : function(browser) {\n *     const loginPage = browser.page.login();\n *     loginPage.api.element('@resultContainer', function(result) {\n *       console.log(result.value)\n *     });\n *   }\n * }\n *\n *\n * @link /#find-element\n * @syntax .element(using, value, callback)\n * @editline L680\n * @deprecated\n * @param {string} using The locator strategy to use.\n * @param {string} value The search target.\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elements\n */\nconst {By} = require('selenium-webdriver');\nconst Element = require('../../element');\n\nmodule.exports = class Session extends ProtocolAction {\n  reportProtocolErrors(result) {\n    return result.code && result.message;\n  }\n\n  command(using, value, callback) {\n    const commandName = 'element';\n\n    if (using instanceof Element || using instanceof By) {\n      return this.findElements({\n        element: using,\n        callback: typeof value == 'function' ? value : callback,\n        commandName\n      });\n    }\n\n    return this.findElements({\n      using, value, commandName, callback\n    });\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementActive.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Get the element on the page that currently has focus. The element will be returned as a [Web Element](https://www.w3.org/TR/webdriver1/#dfn-web-elements) JSON object.\n *\n * @example\n * module.exports = {\n *  'demo Test' : function(browser) {\n *     browser.elementActive(function(result) {\n *       console.log(result.value)\n *     });\n *   }\n * }\n *\n * @name elementActive\n * @editline L866\n * @link /#get-active-element\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementstate\n * @internal\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getActiveElement(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdAttribute.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Get the value of an element's attribute.\n *\n * @link /#get-element-attribute\n * @param {string} webElementId ID of the element to route the command to.\n * @param {string} attributeName The attribute name\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(webElementId, attributeName, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdAttribute');\n\n    return this.transportActions.getElementAttribute(webElementId, attributeName, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdClear.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Scrolls into view a submittable element excluding buttons or editable element, and then attempts to clear its value, reset the checked state, or text content.\n *\n * @link /#dfn-element-clear\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class ElementClear extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdClear');\n\n    return this.transportActions.clearElementValue(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdClick.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Scrolls into view the element and clicks the in-view center point. If the element is not pointer-interactable, an <code>element not interactable</code> error is returned.\n *\n * @link /#element-click\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class ElementClick extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdClick');\n\n    return this.transportActions.clickElement(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdCssProperty.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Retrieve the computed value of the given CSS property of the given element.\n *\n * The CSS property to query should be specified using the CSS property name, not the JavaScript property name (e.g. background-color instead of backgroundColor).\n *\n * @link /#get-element-css-value\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {string} cssPropertyName\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(webElementId, cssPropertyName, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdCssProperty');\n\n    return this.transportActions.getElementCSSValue(webElementId, cssPropertyName, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdDisplayed.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Determine if an element is currently displayed.\n *\n * @link /#element-displayedness\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class Session extends ProtocolAction {\n  async command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdDisplayed');\n\n    return this.transportActions.isElementDisplayed(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdDoubleClick.js",
    "content": "const ProtocolAction = require('./_base-action.js');\nconst {isFunction} = require('../../utils');\n\n/**\n *  Move to the element and performs a double-click in the middle of the given element if element is given else double-clicks at the current mouse coordinates (set by `.moveTo()`).\n *\n * @method elementIdDoubleClick\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.useractions\n */\nmodule.exports = class elementIdDoubleClick extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(webElementId, callback) {\n\n    if (isFunction(webElementId)) {\n      callback = webElementId;\n      webElementId = null;\n    }\n\n    return this.transportActions.doubleClick(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdElement.js",
    "content": "const {LocateStrategy} = require('../../element');\nconst ProtocolAction = require('./_base-action.js');\n\n/**\n * Search for an element on the page, starting from the identified element. The located element will be returned as a Web Element JSON object.\n *\n * This command operates on a protocol level and requires a [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements). Read more on [Element retrieval](https://www.w3.org/TR/webdriver1/#element-retrieval) on the W3C WebDriver spec page.\n *\n * @example\n * module.exports = {\n *  'demo Test' : function(browser) {\n *     browser.elementIdElement('<WebElementId>', 'css selector', '.new-element', function(result) {\n *       console.log(result.value)\n *     });\n *   },\n *\n *   'es6 async demo Test': async function(browser) {\n *     const result = await browser.elementIdElement('<WebElementId>', 'css selector', '.new-element');\n *     console.log(result.value);\n *   },\n *\n *   'page object demo Test': function (browser) {\n *      var nightwatch = browser.page.nightwatch();\n *      nightwatch.navigate();\n *\n *      const navbarHeader = nightwatch.section.navbarHeader;\n *\n *      navbarHeader.api.elementIdElement('@versionDropdown', 'css selector', 'option', function(result) {\n *        browser.assert.ok(client.WEBDRIVER_ELEMENT_ID in result.value, 'The Webdriver Element Id is found in the result');\n *      });\n *   }\n * }\n *\n * @link /#find-element-from-element\n * @syntax .elementIdElement(webElementId, using, value, callback)\n * @editline L794\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {string} using The locator strategy to use.\n * @param {string} value The search target.\n * @param {function} callback Callback function which is called with the result value.\n * @internal\n * @api protocol.elements\n */\nconst Element = require('../../element');\n\nmodule.exports = class Session extends ProtocolAction {\n  command(webElementId, using, value, callback = function (r) {return r}) {\n    const commandName = 'elementIdElement';\n\n    if (webElementId instanceof Element) {\n      return this.findElements({\n        parentElement: webElementId,\n        callback,\n        using,\n        value,\n        commandName\n      });\n    }\n\n    ProtocolAction.validateElementId(webElementId, commandName);\n    LocateStrategy.validate(using, commandName);\n\n    return this.findElements({\n      id: webElementId, using, value, commandName, callback\n    });\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdElements.js",
    "content": "const {LocateStrategy} = require('../../element');\nconst ProtocolAction = require('./_base-action.js');\n\n/**\n * Search for multiple elements on the page, starting from the identified element. The located element will be returned as a web element JSON objects.\n *\n * @example\n * module.exports = {\n *  'demo Test' : function(browser) {\n *     browser.elementIdElements('<WebElementId>', 'css selector', 'ul li', function(result) {\n *       console.log(result.value)\n *     });\n *   },\n *\n *   'es6 async demo Test': async function(browser) {\n *     const result = await browser.elementIdElements('<WebElementId>', 'css selector', 'ul li');\n *     console.log(result.value);\n *   },\n *\n *   'page object demo Test': function (browser) {\n *      var nightwatch = browser.page.nightwatch();\n *      nightwatch.navigate();\n *\n *      const navbarHeader = nightwatch.section.navbarHeader;\n *\n *      navbarHeader.api.elementIdElements('@versionDropdown', 'css selector', 'option', function(result) {\n *        browser.assert.equal(result.value.length, 2, 'There are two option elements in the drop down');\n *      });\n *   }\n * }\n *\n *\n * @link /#find-elements-from-element\n * @syntax .elementIdElements(webElementId, using, value, callback)\n * @editline L840\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {string} using The locator strategy to use.\n * @param {string} value The search target.\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elements\n * @internal\n */\nconst Element = require('../../element');\n\nmodule.exports = class Session extends ProtocolAction {\n  command(webElementId, using, value, callback = function (r) {return r}) {\n    const commandName = 'elementIdElements';\n\n    if (webElementId instanceof Element) {\n      return this.findElements({\n        parentElement: webElementId,\n        callback,\n        using,\n        value,\n        commandName\n      });\n    }\n\n    ProtocolAction.validateElementId(webElementId, 'elementIdElements');\n    LocateStrategy.validate(using, 'elementIdElements');\n\n    return this.findElements({\n      id: webElementId, using, value, commandName, callback\n    });\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdEnabled.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Determine if an element is currently enabled.\n *\n * @link /#is-element-enabled\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdEnabled');\n\n    return this.transportActions.isElementEnabled(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdEquals.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Test if two web element IDs refer to the same DOM element.\n *\n * This command is __deprecated__ and is only available on the [JSON Wire protocol](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidelementidequalsother)\n *\n * @example\n * module.exports = {\n *  'demo Test' : function(browser) {\n *     browser.elementIdEquals('<ID-1>', '<ID-2>', function(result) {\n *       console.log(result.value)\n *     });\n *   }\n * }\n *\n * @link /#finding-elements-to-interact\n * @editline L772\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {string} otherId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the other element to compare against.\n * @param {function} callback Callback function which is called with the result value.\n * @internal\n * @api protocol.elements\n */\nmodule.exports = class Session extends ProtocolAction {\n\n  get w3c_deprecated() {\n    return true;\n  }\n\n  get deprecationNotice() {\n    return 'Please use WebElement.equals(a, b) instead from Selenium Webdriver.';\n  }\n\n  command(webElementId, otherId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdEquals');\n\n    return this.transportActions.elementIdEquals(webElementId, otherId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdLocation.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Determine an element's location on the page. The point (0, 0) refers to the upper-left corner of the page.\n *\n * The element's coordinates are returned as a JSON object with x and y properties.\n *\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @returns {object} The X and Y coordinates for the element on the page.\n */\nmodule.exports = class Session extends ProtocolAction {\n  get w3c_deprecated() {\n    return true;\n  }\n\n  get deprecationNotice() {\n    return 'Please use .getElementRect().';\n  }\n\n  command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdLocation');\n\n    return this.transportActions.getElementRect(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdLocationInView.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Determine an element's location on the screen once it has been scrolled into view.\n *\n * @link\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinternal\n * @deprecated This is a JSON Wire Protocol command and is no longer supported.\n */\nmodule.exports = class Session extends ProtocolAction {\n  get w3c_deprecated() {\n    return true;\n  }\n\n  command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdLocationInView');\n\n    return this.transportActions.isElementLocationInView(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdName.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Retrieve the qualified tag name of the given element.\n *\n * @link /#get-element-tag-name\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdName');\n\n    return this.transportActions.getElementTagName(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdProperty.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Retrieve the value of a specified DOM property for the given element. For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n *\n * @link /#get-element-property\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {string} DOMPropertyName\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class ElementIdProperty extends ProtocolAction {\n  command(webElementId, DOMPropertyName, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdProperty');\n\n    return this.transportActions.getElementProperty(webElementId, DOMPropertyName, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdSelected.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Determine if an OPTION element, or an INPUT element of type checkbox or radio button is currently selected.\n *\n * @link /#is-element-selected\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdSelected');\n\n    return this.transportActions.isElementSelected(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdSize.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Determine an element's size in pixels. The size will be returned as a JSON object with width and height properties.\n *\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class Session extends ProtocolAction {\n  get w3c_deprecated() {\n    return true;\n  }\n\n  get deprecationNotice() {\n    return 'Please use .getElementRect().';\n  }\n\n  command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdSize');\n\n    return this.transportActions.getElementRect(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdText.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Returns the visible text for the element.\n *\n * @link /#get-element-text\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdText');\n\n    return this.transportActions.getElementText(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elementIdValue.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Scrolls into view the form control element and then sends the provided keys to the element, or returns the current value of the element. In case the element is not keyboard interactable, an <code>element not interactable error</code> is returned.\n *\n * @link /#element-send-keys\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {string|array|none} [value] Value to send to element in case of a POST\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.elementinternal\n * @internal\n */\nmodule.exports = class Session extends ProtocolAction {\n  get w3c_deprecated() {\n    return true;\n  }\n\n  command(webElementId, value, callback) {\n    ProtocolAction.validateElementId(webElementId, 'elementIdValue');\n\n    if (arguments.length === 1 || typeof arguments[1] == 'function') {\n      callback = arguments[1] || function (r) {return r};\n\n      return this.transportActions.getElementAttribute(webElementId, 'value', callback);\n    }\n\n    return this.transportActions.setElementValue(webElementId, value, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/elements.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Search for multiple elements on the page, starting from the document root. The located elements will be returned as web element JSON objects.\n * First argument to be passed is the locator strategy, which is detailed on the [WebDriver docs](https://www.w3.org/TR/webdriver/#locator-strategies).\n *\n * The locator strategy can be one of:\n * - `css selector`\n * - `link text`\n * - `partial link text`\n * - `tag name`\n * - `xpath`\n *\n * @example\n * module.exports = {\n *  'demo Test' : function(browser) {\n *     browser.elements('css selector', 'ul li', function(result) {\n *       console.log(result.value)\n *     });\n *   },\n *\n *   'es6 async demo Test': async function(browser) {\n *     const result = await browser.elements('css selector', 'ul li');\n *     console.log('result value is:', result.value);\n *   },\n *\n *   'page object demo Test': function (browser) {\n *      var nightwatch = browser.page.nightwatch();\n *      nightwatch\n *        .navigate()\n *        .assert.titleContains('Nightwatch.js');\n *\n *      nightwatch.api.elements('@featuresList', function(result) {\n *        console.log(result);\n *      });\n *\n *      browser.end();\n *   }\n * }\n *\n * @link /#find-elements\n * @deprecated\n * @syntax .elements(using, value, callback)\n * @editline L734\n * @param {string|null} using The locator strategy to use.\n * @param {string} value The search target.\n * @param {function} callback Callback function to be invoked with the result when the command finishes.\n * @api protocol.elements\n */\nconst Element = require('../../element');\n\nmodule.exports = class Elements extends ProtocolAction {\n  command(using, value, callback) {\n    const commandName = 'elements';\n    let element;\n    if (using instanceof Element) {\n      element = using;\n    } else if (value instanceof Element) {\n      element = value;\n    }\n\n    if (element) {\n      return this.findElements({\n        element,\n        callback: typeof value == 'function' ? value : callback,\n        commandName\n      });\n    }\n\n    return this.findElements({\n      using, value, commandName, callback\n    });\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/forward.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Navigate forward in the browser history, if possible (the equivalent of hitting the browser forward button).\n *\n * @method forward\n * @link /#back\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.navigation\n */\nmodule.exports = class Action extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.navigateForward(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/frame.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Change focus to another frame on the page.\n *\n * Changes the focus of all future commands to another frame on the page. The\n * target frame may be specified as one of the following:\n *\n * - A number that specifies a (zero-based) index into [window.frames](\n *   https://developer.mozilla.org/en-US/docs/Web/API/Window.frames)\n * - An element (css selector) which correspond to a `frame` or `iframe`\n *   DOM element\n * - The `null` value, to select the topmost frame on the page.\n *\n * If the specified frame can not be found, a `NoSuchFrameError` will be thrown\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.frame('<ID>', function(result) {\n *      console.log(result);\n *    });\n * }\n *\n * @method frame\n * @link /#switch-to-frame\n * @param {string|number|null} [frameId] Identifier for the frame to change focus to.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.frames\n */\nconst findElement = function(selector) {\n\n  return new Promise((resolve, reject) => {\n    this.api.findElement({selector, suppressNotFoundErrors: true}, function(res) {\n      if (res.status === -1 && res.error) {\n        return reject(res.error);\n      }\n\n      resolve(res.value);\n    });\n  });\n};\n\nmodule.exports = class Session extends ProtocolAction {\n  static get avoidPrematureParentNodeResolution() {\n    return true;\n  }\n\n  async command(frameId, callback) {\n    if (arguments.length === 1 && typeof frameId === 'function') {\n      callback = frameId;\n\n      return this.transportActions.switchToFrame(callback);\n    }\n\n    if (typeof frameId == 'string') {\n      frameId = await findElement.call(this, frameId)\n        .catch(err => {\n          return findElement.call(this, `*[name=\"${frameId}\"]`);\n        })\n        .catch(err => {\n          return findElement.call(this, `*[id=\"${frameId}\"]`);\n        })\n        .catch(err => {\n          throw new Error(`Unable to locate frame element ${frameId}.`);\n        });\n\n      delete frameId['getId'];\n      frameId.ELEMENT = frameId[Object.keys(frameId)[0]];\n    }\n\n    return this.transportActions.switchToFrame(frameId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/frameParent.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Change focus to the parent context. If the current context is the top level browsing context, the context remains unchanged.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.frameParent(function(result) {\n *      console.log(result);\n *    });\n * }\n *\n * @method frameParent\n * @link /#switch-to-parent-frame\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @since v0.4.8\n * @api protocol.frames\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.switchToParentFrame(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/fullscreenWindow.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Sets the current window state to fullscreen.\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     browser.fullscreenWindow(function(result) {\n *       console.log(result);\n *     });\n *   },\n *\n *   'ES6 async demo Test': async function(browser) {\n *     const result = await browser.fullscreenWindow();\n *     console.log('result value is:', result.value);\n *   }\n * }\n *\n * @link /#dfn-fullscreen-window\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.contexts\n * @deprecated In favour of `.window.fullscreen()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.fullscreenWindow(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/getAlertText.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Gets the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog.\n *\n * @link /#get-alert-text\n * @param {function} callback Callback function which is called with the result value.\n * @returns {string} The text of the currently displayed alert.\n * @api protocol.userprompts\n * @deprecated In favour of `.alerts.getText()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getAlertText(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/getCurrentUrl.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Retrieve the URL of the current page.\n *\n * @example\n * describe('Navigation commands demo', function() {\n *   test('demoTest', function(browser) {\n *     // navigate to new url:\n *     browser.navigateTo('https://nightwatchjs.org');\n *\n *     // Retrieve to url with callback:\n *     browser.getCurrentUrl(function(result) {\n *       console.log(result.value);\n *     });\n *   });\n *\n *   test('demoTestAsync', async function(browser) {\n *     const currentUrl = await browser.navigateTo('https://nightwatchjs.org').getCurrentUrl();\n *     console.log('currentUrl:', currentUrl); // will print 'https://nightwatchjs.org'\n *   });\n *\n * });\n *\n * @method getCurrentUrl\n * @link /#get-current-url\n * @syntax .getCurrentUrl([callback])\n * @param {Function} [callback]\n * @api protocol.navigation\n */\nmodule.exports = class Action extends ProtocolAction {\n  command(callback = function(r) {return r}) {\n    return this.transportActions.getCurrentUrl().then(result => {\n      return callback.call(this.api, result);\n    });\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/getOrientation.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Get the current browser orientation.\n *\n * @param {function} callback Callback function which is called with the result value.\n * @returns {string} The current browser orientation: {LANDSCAPE|PORTRAIT}\n * @api protocol.mobile\n * @deprecated In favour of `.appium.getOrientation()`\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getScreenOrientation(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/keys.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Send a sequence of key strokes to the active element. The sequence is defined in the same format as the `sendKeys` command.\n * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), is loaded onto the main Nightwatch instance as `browser.Keys`.\n *\n * Rather than the `setValue`, the modifiers are not released at the end of the call. The state of the modifier keys is kept between calls, so mouse interactions can be performed while modifier keys are depressed. Pass `client.keys.NULL` to the keys function to release modifiers.\n *\n * **Since v2.0, this command is deprecated.** It is only available on older JSONWire-based drivers. Please use the new [User Actions API](/api/useractions/).\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *    browser\n *      .keys(browser.Keys.CONTROL) // hold down CONTROL key\n *      .click('#element')\n *      .keys(browser.Keys.NULL) // release all keys\n *   }\n * }\n *\n * @param {Array|string} keysToSend The keys sequence to be sent.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.useractions\n * @deprecated\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(keysToSend, callback) {\n    if (!Array.isArray(keysToSend)) {\n      keysToSend = [keysToSend];\n    }\n\n    return this.transportActions.sendKeys(keysToSend, callback);\n  }\n\n  get w3c_deprecated() {\n    return true;\n  }\n\n  get deprecationNotice() {\n    return 'Nightwatch now supports the extended Selenium user actions API which is available via the the .perform() command.';\n  }\n\n};\n"
  },
  {
    "path": "lib/api/protocol/minimizeWindow.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Hides the window in the system tray. If the window happens to be in fullscreen mode, it is restored the normal state then it will be \"iconified\" - minimize or hide the window from the visible screen.\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     browser.minimizeWindow(function(result) {\n *       console.log(result);\n *     });\n *   },\n *\n *   'ES6 async demo Test': async function(browser) {\n *     const result = await browser.minimizeWindow();\n *     console.log('result value is:', result.value);\n *   }\n * }\n *\n * @link /#dfn-minimize-window\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.contexts\n * @deprecated In favour of `.window.minimize()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.minimizeWindow(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/mouseButtonClick.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Click at the current mouse coordinates (set by `.moveTo()`).\n *\n * The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button.\n *\n * **Since v2.0, this command is deprecated.** It is only available on older JSONWire-based drivers. Please use the new [User Actions API](/api/useractions/).\n *\n * @param {string|number} button The mouse button\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.useractions\n */\nmodule.exports = class Command extends ProtocolAction {\n\n  get w3c_deprecated() {\n    return true;\n  }\n\n  get deprecationNotice() {\n    return 'Nightwatch now supports the extended Selenium user actions API which is available via the the .perform() command.';\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  command(button, callback) {\n    return this.mouseButtonHandler('mouseButtonClick', button, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/mouseButtonDown.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Click and hold the left mouse button (at the coordinates set by the last `moveTo` command). Note that the next mouse-related command that should follow is `mouseButtonUp` . Any other mouse command (such as click or another call to buttondown) will yield undefined behaviour.\n *\n * Can be used for implementing drag-and-drop. The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button, and if you don't pass in a button but do pass in a callback, it will handle it correctly.\n *\n * **Since v2.0, this command is deprecated.** It is only available on older JSONWire-based drivers. Please use the new [User Actions API](/api/useractions/).\n *\n * @param {string|number} button The mouse button\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.useractions\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(button, callback) {\n    return this.mouseButtonHandler('mouseButtonDown', button, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/mouseButtonUp.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Releases the mouse button previously held (where the mouse is currently at). Must be called once for every `mouseButtonDown` command issued.\n *\n * Can be used for implementing drag-and-drop. The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button, and if you don't pass in a button but do pass in a callback, it will handle it correctly.\n *\n * * **Since v2.0, this command is deprecated.** It is only available on older JSONWire-based drivers. Please use the new [User Actions API](/api/useractions/).\n *\n * @param {string|number} button The mouse button\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.useractions\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(button, callback) {\n    return this.mouseButtonHandler('mouseButtonUp', button, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/moveTo.js",
    "content": "const {Origin} = require('selenium-webdriver');\nconst Utils = require('../../utils/');\nconst ProtocolAction = require('./_base-action.js');\nconst {isNumber, isString} = Utils;\n\n/**\n * Move the mouse by an offset of the specified [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) or relative to the current mouse cursor, if no element is specified. If an element is provided but no offset, the mouse will be moved to the center of the element.\n *\n * If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.moveTo(null, 110, 100);\n * };\n *\n * @syntax .moveTo([webElementId], xoffset, yoffset, [callback])\n * @syntax .moveTo(null, xoffset, yoffset, [callback])\n * @editline L1335\n * @param {string} [webElementId] The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) assigned to the element to move to. If not specified or is null, the offset is relative to current position of the mouse.\n * @param {number} xoffset X offset to move to, relative to the center of the element. If not specified, the mouse will move to the middle of the element.\n * @param {number} yoffset Y offset to move to, relative to the center of the element. If not specified, the mouse will move to the middle of the element.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.useractions\n */\nmodule.exports = class Command extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(...args) {\n    let webElementId;\n    let xoffset = 0;\n    let yoffset = 0;\n    let callback = function() {};\n\n    const lastItem = args[args.length - 1];\n    if (Utils.isFunction(lastItem)) {\n      args.pop();\n      callback = lastItem;\n    }\n\n    if (isString(args[0]) || arguments[0] === null) {\n      webElementId = args.shift();\n\n      if (webElementId === null) {\n        webElementId = Origin.POINTER;\n      } else {\n        ProtocolAction.validateElementId(webElementId);\n      }\n    }\n\n    if (args.length === 1 && isNumber(args[0]) && !isNaN(args[0])) {\n      xoffset = args[0];\n    } else if (args.length === 2 && isNumber(args[0]) && !isNaN(args[0]) && isNumber(args[1]) && !isNaN(args[1])) {\n      xoffset = args[0];\n      yoffset = args[1];\n    } else if (args.length > 2 || (args.length > 0 && (args[0] !== null || args[1] !== null))) {\n      throw new Error('Invalid Parameters for moveTo Command');\n    }\n\n    if (!webElementId) {\n      webElementId = Origin.POINTER;\n    }\n\n    return this.transportActions.moveTo(webElementId, xoffset, yoffset, callback);\n\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/navigateTo.js",
    "content": "const {Logger, relativeUrl, uriJoin} = require('../../utils');\nconst ProtocolAction = require('./_base-action.js');\n\n/**\n * Navigate to a new URL. This method will also call the `onBrowserNavigate()` test global, right after the page is loaded.\n *\n * @example\n * describe('Navigation commands demo', function() {\n *   test('demoTest', function(browser) {\n *     // navigate to new url:\n *     browser.navigateTo('https://nightwatchjs.org');\n *\n *     // Retrieve to url with callback:\n *     browser.getCurrentUrl(function(result) {\n *       console.log(result.value);\n *     });\n *   });\n *\n *   test('demoTestAsync', async function(browser) {\n *     const currentUrl = await browser.navigateTo('https://nightwatchjs.org').getCurrentUrl();\n *     console.log('currentUrl:', currentUrl); // will print 'https://nightwatchjs.org'\n *   });\n *\n * });\n *\n * @method navigateTo\n * @link /#navigate-to\n * @syntax .navigateTo(url, [callback])\n * @param {string} url The url to navigate to\n * @param {Function} [callback]\n * @api protocol.navigation\n * @since 2.0.0\n */\nmodule.exports = class Action extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(url, callback = function(r) {return r}) {\n    if (typeof url != 'string') {\n      throw new Error('Missing url parameter.');\n    }\n\n    if (relativeUrl(url)) {\n      if (!this.api.baseUrl) {\n        throw new Error(`Invalid URL ${url}. When using relative uris, you must ` +\n          'define a \"baseUrl\" or \"launchUrl\" in your nightwatch config.');\n      }\n\n      url = uriJoin(this.api.baseUrl, url);\n    }\n\n    return this.transportActions.navigateTo(url)\n      .then((result) => {\n        if (result && result.error) {\n          const {error} = result;\n          const {message} = error;\n\n          error.message = `Unable to navigate to url ${url}: ${message}`;\n\n          throw error;\n        }\n\n        return callback.call(this.api, result);\n      })\n      .then(async (result) => {\n        try {\n          await this.settings.globals.onBrowserNavigate(this.api, result);\n        } catch (err) {\n          const error = new Error(`Error during onBrowserNavigate() global hook: ${err.message}`);\n          Logger.error(error);\n        }\n\n        return result;\n      });\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/openNewWindow.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Opens a new top-level browser window, which can be either a tab (default) or a separate new window.\n *\n * This command is only available for W3C Webdriver compatible browsers.\n *\n * @example\n * module.exports = {\n *  'demo Test': function(browser) {\n *     // open a new window tab (default)\n *     browser.openNewWindow(function(result) {\n *       console.log(result);\n *     });\n *\n *     // open a new window\n *     browser.openNewWindow('window', function(result) {\n *       console.log(result);\n *     });\n *   },\n *\n *   'ES6 async demo Test': async function(browser) {\n *     const result = await browser.openNewWindow();\n *     console.log('result value is:', result.value);\n *   }\n * }\n *\n * @link /#dfn-new-window\n * @param {string} [type] Can be either \"tab\" or \"window\", with \"tab\" set to default if none is specified.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.contexts\n * @deprecated In favour of `.window.open()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(type = 'tab', callback) {\n    if (typeof type == 'function' && callback === undefined) {\n      callback = arguments[0];\n      type = 'tab';\n    }\n\n    return this.transportActions.openNewWindow(type, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/quit.js",
    "content": "const {Logger} = require('../../utils');\nconst ProtocolAction = require('./_base-action.js');\n\n/**\n * Ends the session and closes down the test WebDriver server, if one is running. This is similar to calling the .end() command, but the former doesn't quit the WebDriver session.\n *\n * This command will also execute the `onBrowserQuit()` global, if one is defined.\n *\n * @example\n * this.demoTest = function (browser) {\n *   browser.quit(function(result) {\n *     console.log(result.value);\n *   });\n * }\n *\n * @method quit\n * @syntax .quit([callback])\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.sessions\n * @since 2.0.0\n */\nmodule.exports = class Quit extends ProtocolAction {\n  async command(callback = function(r) {return r}) {\n    try {\n      await this.settings.globals.onBrowserQuit(this.api);\n    } catch (err) {\n      const error = new Error(`Error during onBrowserQuit() global hook: ${err.message}`);\n      Logger.error(error);\n    }\n\n    return this.transportActions.sessionAction('DELETE').then(async (result) => {\n      try {\n        await callback.call(this.api, result);\n      } catch (err) {\n        const error = new Error(`Error while quiting: ${err.message}`);\n        Logger.error(error);\n      }\n\n      this.client.sessionId = null;\n      await this.transport.sessionFinished('FINISHED');\n    });\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/refresh.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Refresh the current page.\n *\n * @method refresh\n * @link /#refresh\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.navigation\n */\nmodule.exports = class Action extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.pageRefresh(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/releaseMouseButton.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n/**\n * Release the depressed left mouse button at the current mouse coordinates (set by `.moveTo()`).\n *\n *\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.useractions\n */\nmodule.exports = class Command extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.release(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/screenshot.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Take a screenshot of the current page.\n *\n * @method screenshot\n * @link /#take-screenshot\n * @param {boolean} log_screenshot_data Whether or not the screenshot data should appear in the logs when running with --verbose\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.screens\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(log_screenshot_data = false, callback = function (r) {return r}) {\n    if (arguments.length === 1 && typeof arguments[0] === 'function') {\n      return this.transportActions.getScreenshot(false, arguments[0]);\n    }\n\n    return this.transportActions.getScreenshot(log_screenshot_data, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/session.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Get info about, delete or create a new session. Defaults to the current session.\n *\n * @example\n * this.demoTest = function (browser) {\n *    browser.session(function(result) {\n *      console.log(result.value);\n *    });\n *    //\n *    browser.session('delete', function(result) {\n *      console.log(result.value);\n *    });\n *    //\n *    browser.session('delete', '12345-abc', function(result) {\n *      console.log(result.value);\n *    });\n * }\n *\n *\n * @method session\n * @link /#new-session\n * @editline L141\n * @syntax .session([action], [sessionId], [callback])\n * @param {string} [action] The http verb to use, can be \"get\", \"post\" or \"delete\". If only the callback is passed, get is assumed by default.\n * @param {string} [sessionId] The id of the session to get info about or delete.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.sessions\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get SessionActions() {\n    return {\n      GET: 'GET',\n      POST: 'POST',\n      DELETE: 'DELETE'\n    };\n  }\n\n  command(action = Session.SessionActions.GET, sessionId, callback) {\n    if (arguments.length === 1 && typeof arguments[0] == 'function') {\n      callback = arguments[0];\n      action = Session.SessionActions.GET;\n    } else if (arguments[0] && !(arguments[0].toUpperCase() in Session.SessionActions)) {\n      sessionId = arguments[0];\n      action = Session.SessionActions.GET;\n    }\n\n    if (typeof arguments[1] === 'function') {\n      callback = arguments[1];\n      sessionId = this.api.sessionId;\n    }\n\n    action = action.toUpperCase();\n\n    if (action !== Session.SessionActions.POST && !sessionId) {\n      sessionId = this.api.sessionId;\n    }\n\n    return this.transportActions.sessionAction(action, sessionId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/sessionLog.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Gets the text of the log type specified. To find out the available log types, use `.getLogTypes()`.\n *\n * Returns a [log entry JSON object](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#log-entry-json-object).\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.sessionLog('client', function(result) {\n *      console.log(result.value);\n *    });\n * }\n *\n * @syntax .sessionLog(typeString, callback)\n * @param {string} typeString Type of log to request. Can be one of: client, driver, browser, server\n * @param {function} callback Callback function which is called with the result value.\n * @returns {Array} Array of the text entries of the log.\n * @api protocol.sessions\n * @deprecated In favour of `.logs.getSessionLog()`.\n */\nmodule.exports = class Action extends ProtocolAction {\n  command(typeString, callback) {\n    return this.transportActions.getLogContents(typeString, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/sessionLogTypes.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Gets an array of strings for which log types are available. This methods returns the entire WebDriver response, if you are only interested in the logs array, use `.getLogTypes()` instead.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.sessionLogTypes(function(result) {\n *      console.log(result.value);\n *    });\n * }\n *\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.sessions\n * @deprecated In favour of `.logs.getSessionLogTypes()`.\n */\nmodule.exports = class Action extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getSessionLogTypes(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/sessions.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Returns a list of the currently active sessions.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.sessions(function(result) {\n *      console.log(result.value);\n *    });\n * }\n *\n * @method sessions\n * @editline L166\n * @section sessions\n * @syntax .sessions(callback)\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.sessions\n */\nmodule.exports = class Sessions extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getSessions(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/setAlertText.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Sends keystrokes to a JavaScript prompt() dialog.\n *\n * @link /#send-alert-text\n * @param {string} value Keystrokes to send to the prompt() dialog\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.userprompts\n * @deprecated In favour of `.alerts.setText()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(value, callback) {\n    return this.transportActions.setAlertText(value, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/setContext.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Sets the context.\n *\n * @param {string} context context name to switch to - a string representing an available context.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.mobile\n * @deprecated In favour of `.appium.setContext()`\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(context, callback) {\n    return this.transportActions.setCurrentContext(context, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/setOrientation.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Sets the browser orientation.\n *\n * @param {string} orientation The new browser orientation: {LANDSCAPE|PORTRAIT}\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.mobile\n * @deprecated In favour of `.appium.setOrientation()`\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(orientation, callback) {\n    orientation = orientation.toUpperCase();\n\n    if (!ProtocolAction.ScreenOrientation.includes(orientation)) {\n      throw new Error('Invalid screen orientation value specified. Accepted values are: ' + ProtocolAction.ScreenOrientation.join(', '));\n    }\n\n    return this.transportActions.setScreenOrientation(orientation, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/source.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Returns a string serialisation of the DOM of the current page.\n *\n * @link /#getting-page-source\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.document\n * @deprecated In favour of `.document.source()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getPageSource(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/status.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Query the server's current status.\n *\n * @method status\n * @link /#status\n * @syntax .status([callback])\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.sessions\n */\nmodule.exports = class Action extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getStatus(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/submit.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Submit a FORM element. The submit command may also be applied to any element that is a descendant of a FORM element.\n *\n * @method submit\n * @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.elementinternal\n */\nmodule.exports = class Session extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(webElementId, callback) {\n    ProtocolAction.validateElementId(webElementId, 'submit');\n\n    return this.transportActions.elementSubmit(webElementId, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/switchToWindow.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Change focus to another window. The window to change focus to may be specified by its server assigned window handle, or by the value of its name attribute.\n *\n * To find out the window handle use `windowHandles` command\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.windowHandles(function(result) {\n *      var handle = result.value[0];\n *      browser.switchToWindow(handle);\n *    });\n *  };\n *\n *  this.demoTestAsync = async function (browser) {\n *    const result = await browser.windowHandles();\n *    var handle = result.value[0];\n *    browser.switchToWindow(handle);\n *  };\n *\n *\n * @method switchToWindow\n * @param {string} handleOrName The server assigned window handle or the name attribute.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @see window\n * @api protocol.contexts\n * @deprecated In favour of `.window.switchTo()`.\n */\nmodule.exports = class Action extends ProtocolAction {\n  static get namespacedAliases() {\n    return 'switchWindow';\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  command(handleOrName, callback) {\n    // TODO: error handling\n\n    return this.transportActions.switchToWindow(handleOrName, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/timeouts.js",
    "content": "const Utils = require('../../utils');\nconst ProtocolAction = require('./_base-action.js');\n\n/**\n * Configure or retrieve the amount of time that a particular type of operation can execute for before they are aborted and a |Timeout| error is returned to the client.\n *\n * If called with only a callback as argument, the command will return the existing configured timeout values.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.timeouts('script', 10000, function(result) {\n *      console.log(result);\n *    });\n *\n *    browser.timeouts(function(result) {\n *      console.log('timeouts', result);\n *    });\n * }\n *\n * @method timeouts\n * @link /#set-timeout\n * @editline L188Í\n * @syntax .timeouts([callback])\n * @syntax .timeouts(type, ms, [callback])\n * @section sessions\n * @param {string} type The type of operation to set the timeout for. Valid values are \"script\" for script timeouts, \"implicit\" for modifying the implicit wait timeout and \"pageLoad\" (or \"page load\" for legacy JsonWire) for setting a page load timeout.\n * @param {number} ms The amount of time, in milliseconds, that time-limited commands are permitted to run.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.sessions\n */\nmodule.exports = class Timeouts extends ProtocolAction {\n  static get TimeoutTypes() {\n    return [\n      'script',\n      'implicit',\n      'pageLoad'\n    ];\n  }\n\n  command(type, ms, callback) {\n    if (Utils.isFunction(type) && arguments.length === 1 || arguments.length === 0) {\n      return this.transportActions.getTimeouts(type);\n    }\n\n    if (!Timeouts.TimeoutTypes.includes(type)) {\n      throw new Error(`Invalid timeouts type value: ${type}. Accepted values are: ${Timeouts.TimeoutTypes.join(', ')}`);\n    }\n\n    if (typeof ms != 'number') {\n      throw new Error(`Second argument to .timeouts() command must be a number. ${ms} given.`);\n    }\n\n    return this.transportActions.setTimeoutType(type, ms, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/timeoutsAsyncScript.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Set the amount of time, in milliseconds, that asynchronous scripts executed by `.executeAsync` are permitted to run before they are aborted and a |Timeout| error is returned to the client.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.timeoutsAsyncScript(10000, function(result) {\n *      console.log(result);\n *    });\n * }\n *\n * @method timeoutsAsyncScript\n * @syntax .timeoutsAsyncScript(ms, [callback])\n * @jsonwire\n * @param {number} ms The amount of time, in milliseconds, that time-limited commands are permitted to run.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.sessions\n */\nmodule.exports = class Action extends ProtocolAction {\n  command(ms, callback) {\n    if (typeof ms != 'number') {\n      throw new Error(`First argument to .timeoutsAsyncScript() command must be a number. ${typeof ms} given: ${ms}`);\n    }\n\n    return this.transportActions.setTimeoutsAsyncScript(ms, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/timeoutsImplicitWait.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Set the amount of time the driver should wait when searching for elements. If this command is never sent, the driver will default to an implicit wait of 0ms.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.timeoutsImplicitWait(10000, function(result) {\n *      console.log(result);\n *    });\n * }\n *\n * @method timeoutsImplicitWait\n * @jsonwire\n * @syntax .timeoutsImplicitWait(ms, [callback])\n * @param {number} ms The amount of time, in milliseconds, that time-limited commands are permitted to run.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.sessions\n */\nmodule.exports = class Action extends ProtocolAction {\n  command(ms, callback) {\n    if (typeof ms != 'number') {\n      throw new Error(`First argument to .timeoutsImplicitWait() command must be a number. ${typeof ms} given: ${ms}`);\n    }\n\n    return this.transportActions.setTimeoutsImplicitWait(ms, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/title.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Get the current page title.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.title(function(result) {\n *      console.log(result.value);\n *    });\n * }\n *\n * @link /#get-title\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.navigation\n */\nmodule.exports = class Action extends ProtocolAction {\n  command(callback) {\n    return this.transportActions.getPageTitle(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/url.js",
    "content": "const ProtocolAction = require('./_base-action.js');\nconst ora = require('ora');\n\n/**\n * Retrieve the URL of the current page or navigate to a new URL.\n *\n * @example\n * module.exports = {\n *  'demo Test' : function(browser) {\n *     browser.url(function(result) {\n *       // return the current url\n *       console.log(result);\n *     });\n *\n *     // navigate to new url:\n *     browser.url('{URL}');\n *\n *     // navigate to new url:\n *     browser.url('{URL}', function(result) {\n *       console.log(result);\n *     });\n *   }\n * }\n *\n * @method url\n * @link /#navigate-to\n * @syntax .url([url], [callback])\n * @syntax .url(callback)\n * @param {string|function} [url] If missing, it will return the URL of the current page as an argument to the supplied callback.\n * @param {Function} [callback]\n * @api protocol.navigation\n */\nmodule.exports = class Action extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(url, callback = function(r) {return r}) {\n    if (typeof url == 'string') {\n      const startTime = new Date();\n      let spinner;\n      if (this.settings.output) {\n        spinner = ora({\n          text: `Loading url: ${url}\\n`,\n          prefixText: ' ',\n          discardStdin: false\n        }).start();\n      }\n\n      return this.transportActions.navigateTo(url).then(result => {\n        if (spinner) {\n          const ms = new Date() - startTime;\n          spinner.info(`Loaded url ${url} in ${ms}ms`);\n        }\n\n        return callback.call(this.api, result);\n      });\n    }\n\n    if (typeof url == 'function') {\n      callback = url;\n    }\n\n    return this.transportActions.getCurrentUrl().then(result => {\n      return callback.call(this.api, result);\n    });\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/waitUntil.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Waits for a condition to evaluate to a \"truthy\" value. The condition may be specified by any function which\n * returns the value to be evaluated or a Promise to wait for.\n *\n * An optional wait time can be specified, otherwise the global waitForConditionTimeout value will be used.\n *\n * @example\n * describe('waitUntil Example', function() {\n *   it('demo Test', function(browser) {\n *     browser\n *       .url('https://nightwatchjs.org)\n *       .waitUntil(async function() {\n *         const title = await this.execute(function() {\n *           return document.title;\n *         });\n *\n *         return title === 'Nightwatch.js';\n *       }, 1000);\n *   });\n * }\n *\n * @method waitUntil\n * @link https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebDriver.html#wait\n * @selenium_webdriver\n * @syntax .waitUntil(conditionFn, [callback])\n * @syntax .waitUntil(conditionFn, [waitTimeMs], [callback])\n * @syntax .waitUntil(conditionFn, [waitTimeMs], [retryInterval], [callback])\n * @syntax .waitUntil(conditionFn, [waitTimeMs], [retryInterval], [message], [callback])\n * @param {function} conditionFn The condition to wait on, defined as function which returns a Promise\n * @param {number} [waitTimeMs] How long to wait for the condition to be true (in milliseconds).\n * @param {number} [retryInterval] The interval to use between checks (in milliseconds).\n * @param {Function} [callback] An optional callback which will be called with the result\n * @api protocol.utilities\n * @since 2.0.0\n */\nconst {makePromise, isFunction, isUndefined, isNumber, isString} = require('../../utils');\n\nmodule.exports = class WaitUntil extends ProtocolAction {\n  get requiresSeleniumWebdriver() {\n    return true;\n  }\n\n  static isParamTypeValid(param, expectedType) {\n    if (typeof param !== expectedType) {\n      // eslint-disable-next-line no-console\n      console.warn(`Expected \"${expectedType}\" argument type for ${param}; \"${typeof param}\" given – using default value`);\n\n      return false;\n    }\n\n    return true;\n  }\n\n  static hasMessage(msg) {\n    return isString(msg) && msg || (msg instanceof Error);\n  }\n\n  static get isTraceable() {\n    return true;\n  }\n\n  static get avoidPrematureParentNodeResolution() {\n    return true;\n  }\n\n  static get rejectNodeOnAbortFailure() {\n    return true;\n  }\n\n  //timeMs, retryInterval, message, callback = function(r) {return r}\n  async command(conditionFn, ...args) {\n    let callback = function(r) {return r};\n    let message;\n    let timeMs = this.settings.globals.waitForConditionTimeout;\n    let retryInterval = this.settings.globals.waitForConditionPollInterval;\n\n    if (args.length >= 3 && WaitUntil.hasMessage(args[2])) {\n      timeMs = WaitUntil.isParamTypeValid(args[0], 'number') ? args[0] : timeMs;\n      retryInterval = WaitUntil.isParamTypeValid(args[1], 'number') ? args[1] : retryInterval;\n      message = args[2];\n      callback = isFunction(args[3]) ? args[3] : callback;\n    } else {\n      switch (args.length) {\n        case 2:\n        case 3:\n          timeMs = WaitUntil.isParamTypeValid(args[0], 'number') ? args[0] : timeMs;\n\n          if (isFunction(args[1]) && isUndefined(args[2])) {\n            callback = args[1];\n          } else {\n            retryInterval = WaitUntil.isParamTypeValid(args[1], 'number') ? args[1] : retryInterval;\n            callback = !isUndefined(args[2]) && WaitUntil.isParamTypeValid(args[2], 'function') ? args[2] : callback;\n          }\n\n          break;\n\n        case 1:\n          if (isFunction(args[0])) {\n            callback = args[0];\n          } else if (isNumber(args[0])) {\n            timeMs = args[0];\n          }\n          break;\n      }\n    }\n\n    const result = await this.transportActions.wait(() => {\n      return conditionFn.bind(this.api);\n    }, timeMs, isString(message) ? message : '', retryInterval);\n\n    if (result && result.error instanceof Error) {\n      await callback(result);\n\n      if (message instanceof Error) {\n        throw message;\n      }\n\n      throw result.error;\n    }\n\n    return makePromise(callback, this.api, [result]);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/windowHandle.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Retrieve the current window handle.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.windowHandle(function(result) {\n *      console.log(result.value);\n *    });\n * }\n *\n * @link /#get-window-handle\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.window\n * @deprecated In favour of `.window.getHandle()`.\n */\nmodule.exports = class Action extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.getWindowHandle(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/windowHandles.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Retrieve the list of all window handles available to the session.\n *\n * @example\n *  this.demoTest = function (browser) {\n *    browser.windowHandles(function(result) {\n *      // An array of window handles.\n *      console.log(result.value);\n *    });\n * }\n *\n * @link /#get-window-handles\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.window\n * @deprecated In favour of `.window.getAllHandles()`.\n */\nmodule.exports = class Action extends ProtocolAction {\n  static get isTraceable() {\n    return true;\n  }\n\n  command(callback) {\n    return this.transportActions.getAllWindowHandles(callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/windowMaximize.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Increases the window to the maximum available size without going full-screen.\n *\n * @example\n * module.exports = {\n *  'demo Test with W3C Webdriver clients': function(browser) {\n *     // W3C Webdriver API doesn't require the window handle parameter anymore\n *     browser.windowMaximize(function(result) {\n *       console.log(result);\n *     });\n *   },\n *\n *   'ES6 async demo Test': async function(browser) {\n *     const result = await browser.windowMaximize();\n *     console.log('result value is:', result.value);\n *   },\n *\n *   'when using JSONWire (deprecated) clients': function(browser) {\n *      browser.windowMaximize('current', function(result) {\n *        console.log(result);\n *      });\n *   }\n * }\n *\n * @link /#dfn-maximize-window\n * @param {string} [handleOrName] Only required when using non-W3C Webdriver protocols (such as JSONWire). windowHandle URL parameter; if it is \"current\", the currently active window will be maximized.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.window\n * @deprecated In favour of `.window.maximize()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(handleOrName = 'current', callback) {\n    return this.transportActions.maximizeWindow(handleOrName, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/windowPosition.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Change or get the position of the specified window. If the second argument is a function it will be used as a callback and the call will perform a get request to retrieve the existing window position.\n *\n * @example\n *  this.demoTest = function (browser) {\n *\n *    // Change the position of the specified window.\n *    // If the :windowHandle URL parameter is \"current\", the currently active window will be moved.\n *    browser.windowPosition('current', 0, 0, function(result) {\n *      console.log(result);\n *    });\n *\n *    // Get the position of the specified window.\n *    // If the :windowHandle URL parameter is \"current\", the position of the currently active window will be returned.\n *    browser.windowPosition('current', function(result) {\n *      console.log(result.value);\n *    });\n * }\n *\n * @see windowRect\n * @jsonwire\n * @param {string} windowHandle\n * @param {number} offsetX\n * @param {number} offsetY\n * @param {function} callback Callback function which is called with the result value.\n * @api protocol.window\n * @deprecated In favour of `.window.getPosition()` and `.window.setPosition()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(windowHandle, offsetX, offsetY, callback) {\n    if (typeof windowHandle !== 'string') {\n      throw new Error('First argument must be a window handle string.');\n    }\n\n    if (arguments.length <= 2) {\n      if (typeof arguments[1] != 'function') {\n        throw new Error(`Second argument passed to .windowPosition() should be a callback when not passing offsetX and offsetY - ${typeof arguments[1]} given.`);\n      }\n\n      return this.transportActions.getWindowPosition(windowHandle, arguments[1]);\n    }\n\n    offsetX = Number(offsetX);\n    offsetY = Number(offsetY);\n\n    if (typeof offsetX !== 'number' || isNaN(offsetX)) {\n      throw new Error('offsetX argument passed to .windowPosition() must be a number.');\n    }\n\n    if (typeof offsetY !== 'number' || isNaN(offsetY)) {\n      throw new Error('offsetY argument passed to .windowPosition() must be a number.');\n    }\n\n    return this.transportActions.setWindowPosition(offsetX, offsetY, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/windowRect.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Change or get the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect). This is defined as a dictionary of the `screenX`, `screenY`, `outerWidth` and `outerHeight` attributes of the window.\n *\n * Its JSON representation is the following:\n * - `x` - window's screenX attribute;\n * - `y` - window's screenY attribute;\n * - `width` - outerWidth attribute;\n * - `height` - outerHeight attribute.\n *\n * All attributes are in in CSS pixels. To change the window react, you can either specify `width` and `height`, `x` and `y` or all properties together.\n *\n * @example\n * module.exports = {\n *   'demo test .windowRect()': function(browser) {\n *\n *      // Change the screenX and screenY attributes of the window rect.\n *      browser.windowRect({x: 500, y: 500});\n *\n *      // Change the width and height attributes of the window rect.\n *      browser.windowRect({width: 600, height: 300});\n *\n *      // Retrieve the attributes\n *      browser.windowRect(null, function(result) {\n *        console.log(result.value);\n *      });\n *   },\n *\n *   'windowRect ES6 demo test': async function(browser) {\n *      const resultValue = await browser.windowRect(null);\n *      console.log('result value', resultValue);\n *   }\n * }\n *\n * @w3c\n * @link /#dfn-get-window-rect\n * @syntax .windowRect({width, height, x, y}, [callback]);\n * @param {object} options An object specifying either `width` and `height`, `x` and `y`, or all together to set properties for the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect).\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.window\n * @deprecated In favour of `.window.getRect()` and `.window.setRect()`.\n */\nconst Utils = require('../../utils');\n\nmodule.exports = class Session extends ProtocolAction {\n  command(options, callback = function(r) {return r}) {\n    if (arguments[0] === null) {\n      return this.transportActions.getWindowRect(callback);\n    }\n\n    const {width, height, x, y} = options;\n\n    if (!Utils.isUndefined(width) && !Utils.isNumber(width)) {\n      throw new Error(`Width argument passed to .windowRect() must be a number; received: ${typeof width} (${width}).`);\n    }\n\n    if (!Utils.isUndefined(height) && !Utils.isNumber(height)) {\n      throw new Error(`Height argument passed to .windowRect() must be a number; received: ${typeof height} (${height}).`);\n    }\n\n    if (Utils.isNumber(width) && !Utils.isNumber(height) ||\n      !Utils.isNumber(width) && Utils.isNumber(height)\n    ) {\n      throw new Error('Attributes \"width\" and \"height\" must be specified together.');\n    }\n\n    if (!Utils.isUndefined(x) && !Utils.isNumber(x)) {\n      throw new Error(`X position argument passed to .windowRect() must be a number; received: ${typeof x} (${x}).`);\n    }\n\n    if (!Utils.isUndefined(y) && !Utils.isNumber(y)) {\n      throw new Error(`Y position argument passed to .windowRect() must be a number; received: ${typeof y} (${y}).`);\n    }\n\n    if (Utils.isNumber(x) && !Utils.isNumber(y) ||\n      !Utils.isNumber(x) && Utils.isNumber(y)\n    ) {\n      throw new Error('Attributes \"x\" and \"y\" must be specified together.');\n    }\n\n    return this.transportActions.setWindowRect(arguments[0], callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/protocol/windowSize.js",
    "content": "const ProtocolAction = require('./_base-action.js');\n\n/**\n * Change or get the size of the specified window. If the second argument is a function it will be used as a callback and the call will perform a get request to retrieve the existing window size.\n *\n * @example\n *  this.demoTest = function (browser) {\n *\n *    // Return the size of the specified window. If the :windowHandle URL parameter is \"current\", the size of the currently active window will be returned.\n *    browser.windowSize('current', function(result) {\n *      console.log(result.value);\n *    });\n *\n *    // Change the size of the specified window.\n *    // If the :windowHandle URL parameter is \"current\", the currently active window will be resized.\n *    browser.windowSize('current', 300, 300, function(result) {\n *      console.log(result.value);\n *    });\n * }\n *\n * @see windowRect\n * @jsonwire\n * @param {string} windowHandle\n * @param {number} width\n * @param {number} height\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol.window\n * @deprecated In favour of `.window.getSize()` and `.window.setSize()`.\n */\nmodule.exports = class Session extends ProtocolAction {\n  command(windowHandle, width, height, callback) {\n    if (typeof windowHandle !== 'string') {\n      throw new Error('First argument must be a window handle string.');\n    }\n\n    if (arguments.length <= 2) {\n      if (typeof arguments[1] != 'function') {\n        throw new Error(`Second argument passed to .windowSize() should be a callback when not passing width and height - ${typeof arguments[1]} given.`);\n      }\n\n      return this.transportActions.getWindowSize(windowHandle, arguments[1]);\n    }\n\n    width = Number(width);\n    height = Number(height);\n\n    if (typeof width !== 'number' || isNaN(width)) {\n      throw new Error('Width argument passed to .windowSize() must be a number.');\n    }\n\n    if (typeof height !== 'number' || isNaN(height)) {\n      throw new Error('Height argument passed to .windowSize() must be a number.');\n    }\n\n    return this.transportActions.setWindowSize(width, height, callback);\n  }\n};\n"
  },
  {
    "path": "lib/api/web-element/assert/element-assertions.js",
    "content": "const {WebElement} = require('selenium-webdriver');\n\nclass ScopedElementAssertions {\n  constructor(scopedElement, {negated, nightwatchInstance}) {\n    this.negated = negated;\n    this.scopedElement = scopedElement;\n    this.nightwatchInstance = nightwatchInstance;\n  }\n\n  assert(callback) {\n    // The below promise is returned to the test case by the assertion, so\n    // it should fail in case the actual assertion (callback) fails. In case\n    // of a sync test, the actual assertion would never fail, so we always\n    // resolve the promise.\n    const assertPromise = new Promise((resolve, reject) => {\n      const assert = this.nightwatchInstance.api.assert;\n\n      const callbackResult = callback(this.negated ? assert.not : assert, this.scopedElement.webElement);\n      if (callbackResult instanceof Promise) {\n        callbackResult\n          .then(() => {\n            resolve(this.scopedElement);\n          })\n          .catch(err => {\n            reject(err);\n          });\n      } else {\n        resolve(this.scopedElement);\n      }\n    });\n\n    // prevent unhandledRejection errors, while also making sure\n    // that the exception/failure passes to the actual test case.\n    assertPromise.catch(() => {});\n\n    return assertPromise;\n  }\n\n  async executeScript(scriptFn, args) {\n    return this.nightwatchInstance.transportActions.executeScript(scriptFn, [this.scopedElement.webElement, ...args]).then(({value}) => value);\n  }\n}\n\nmodule.exports.create = function createAssertions(scopedElement, {negated = false, nightwatchInstance}) {\n  const instance = new ScopedElementAssertions(scopedElement, {\n    negated,\n    nightwatchInstance\n  });\n\n  const exported = {};\n  Object.defineProperty(exported, 'not', {\n    get() {\n      return createAssertions(scopedElement, {\n        negated: true,\n        nightwatchInstance\n      });\n    }\n  });\n\n  Object.defineProperties(exported, {\n    enabled: {\n      value(message) {\n        return instance.assert((assertApi, element) => assertApi.enabled(element, message));\n      },\n      enumerable: true,\n      configurable: false\n    },\n    selected: {\n      value(message) {\n        return instance.assert((assertApi, element) => assertApi.selected(element, message));\n      },\n      enumerable: true,\n      configurable: false\n    },\n    visible: {\n      value(message) {\n        return instance.assert((assertApi, element) => assertApi.visible(element, message));\n      },\n      enumerable: true,\n      configurable: false\n    },\n    hasDescendants: {\n      value(message) {\n        return instance.assert((assertApi, element) => assertApi.hasDescendants(element, message));\n      },\n      enumerable: true,\n      configurable: false\n    },\n    present: {\n      value(message) {\n        return instance.assert(async (assertApi, element) => {\n          const el = await element;\n          const id = await el?.getId();\n\n          return assertApi.ok(el instanceof WebElement, message || `Testing if the element <WebElement: ${id}> is present.`);\n        });\n      },\n      enumerable: true,\n      configurable: false\n    },\n    hasClass: {\n      async value(name, message = `Testing if the element has \"${name}\" class.`) {\n        const result = await instance.executeScript(function(element, className) {\n          return element.classList.contains(className);\n        }, [name]);\n\n        return instance.assert((assertApi) => assertApi.ok(result, message));\n      },\n      enumerable: true,\n      configurable: false\n    },\n\n    hasAttribute: {\n      async value(name, message = `Testing if the element has \"${name}\" attribute.`) {\n        const result = await instance.executeScript(function(element, attributeName) {\n          return element.hasAttribute(attributeName);\n        }, [name]);\n\n        return instance.assert((assertApi) => assertApi.ok(result, message));\n      },\n      enumerable: true,\n      configurable: false\n    },\n\n    customScript: {\n      async value(scriptFn = function(el) {return el}, args = [], message = '') {\n        const result = await instance.executeScript(scriptFn, args);\n\n        return instance.assert((assertApi) => assertApi.ok(result, message));\n      },\n      enumerable: true,\n      configurable: false\n    }\n  });\n\n  return exported;\n};\n"
  },
  {
    "path": "lib/api/web-element/assert/elements-assertions.js",
    "content": "class ElementsAssertions {\n  constructor(scopedElements, {negated, nightwatchInstance}) {\n    this.negated = negated;\n    this.scopedElements = scopedElements;\n    this.nightwatchInstance = nightwatchInstance;\n  }\n\n  get not() {\n    return new ElementsAssertions(this.scopedElements, {\n      negated: true,\n      nightwatchInstance: this.nightwatchInstance\n    });\n  }\n}\n\nmodule.exports.ScopedElementsAssertions = ElementsAssertions;\n"
  },
  {
    "path": "lib/api/web-element/assert/value-assertions.js",
    "content": "const AssertionError = require('assertion-error');\n\nmodule.exports.create = function createAssertions(scopedValue, {negated, nightwatchInstance}) {\n\n  class ValueAssertions {\n    constructor(scopedValue, {negated}) {\n      this.negated = negated;\n      this.scopedValue = scopedValue;\n    }\n\n    _assert(callback) {\n      // The below promise is returned to the test case by the assertion, so\n      // it should fail in case the actual assertion (callback) fails. In case\n      // of a sync test, the actual assertion would never fail, so we always\n      // resolve the promise.\n      const assertPromise = new Promise((resolve, reject) => {\n        const assert = nightwatchInstance.api.assert;\n        const callbackResult = callback(this.negated ? assert.not : assert, this.scopedValue.value);\n        if (callbackResult instanceof Promise) {\n          callbackResult\n            .then(() => {\n              resolve(this.scopedValue);\n            })\n            .catch(err => {\n              reject(err);\n            });\n        } else {\n          resolve(this.scopedValue);\n        }\n      });\n\n      // prevent unhandledRejection errors, while also making sure\n      // that the exception/failure passes to the actual test case.\n      assertPromise.catch((err) => {});\n\n      return assertPromise;\n    }\n\n    get not() {\n      return createAssertions(this.scopedValue, {\n        negated: true,\n        nightwatchInstance\n      });\n    }\n\n    contains(expected, message) {\n      return this._assert((assertApi, value) => {\n        return assertApi.promisedValue({\n          callback() {\n            return value;\n          }, verb: 'contains', message, expected, evaluate(value) {\n            return value.includes(expected);\n          }, timeout: 0\n        });\n      });\n    }\n\n    equals(expected, message) {\n      return this._assert((assertApi, value) => {\n        return assertApi.promisedValue({\n          callback() {\n            return value;\n          }, verb: 'equals', message, expected, evaluate(value) {\n            return value === expected;\n          }, timeout: 0\n        });\n      });\n    }\n\n    matches(expected, message) {\n      return this._assert((assertApi, value) => {\n        return assertApi.promisedValue({\n          callback() {\n            return value;\n          }, verb: 'contains', message, expected, evaluate(value) {\n            return expected.test(value);\n          }, failure(expected) {\n            if (expected instanceof RegExp) {\n              return null;\n            }\n\n            return new AssertionError(`Expected value must be a regular expression; ${typeof expected} given.`);\n          }, timeout: 0\n        });\n      });\n    }\n  }\n\n  return new ValueAssertions(scopedValue, {\n    negated\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/check.js",
    "content": "/**\n * Will check, by clicking, on a checkbox or radio input if it is not already checked.\n * The element is scrolled into view if it is not already pointer-interactable. See the WebDriver specification for <a href=\"https://www.w3.org/TR/webdriver/#element-interactability\" target=\"_blank\">element interactability</a>.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('input[type=checkbox]:not(:checked)').check();\n *     browser.element('input[type=radio]:not(:checked)').check();\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('input[type=checkbox]:not(:checked)').check();\n *     await browser.element('input[type=radio]:not(:checked)').check();\n *   },\n * }\n *\n * @since 3.7.0\n * @method check\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).check()\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommand('checkElement');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/clear.js",
    "content": "/**\n * Clear a textarea or a text input element's value.\n * This command has no effect if the underlying DOM element is neither a text INPUT element nor a TEXTAREA element.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('input[type=text]').clear();\n *\n *     browser.element('textarea').clear();\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('input[type=text]').clear();\n *\n *     await browser.element('textarea').clear();\n *   }\n * }\n *\n * @since 3.0.0\n * @method clear\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).clear()\n * @link /#dfn-element-clear\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommand('clearElementValue');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/click.js",
    "content": "/**\n * Simulates a click event on the given DOM element.\n * The element is scrolled into view if it is not already pointer-interactable. See the WebDriver specification for <a href=\"https://www.w3.org/TR/webdriver/#element-interactability\" target=\"_blank\">element interactability</a>.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('button.submit-form').click();\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('button.submit-form').click();\n *   }\n * }\n *\n * @since 3.0.0\n * @method click\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).click()\n * @link /#dfn-element-click\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommand('clickElement');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/clickAndHold.js",
    "content": "/**\n * Move to the element and click (without releasing) in the middle of the given element.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('button.submit-form').clickAndHold();\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('button.submit-form').clickAndHold();\n *   }\n * }\n *\n * @since 3.0.0\n * @method clickAndHold\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).clickAndHold()\n * @see https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#click-and-hold\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommand('pressAndHold');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/doubleClick.js",
    "content": "/**\n * Move to the element and peforms a double-click in the middle of the element.\n *\n * <p class=\"alert alert-info\">The command <code>doubleClick()</code> will automatically wait for the element to be present (until the specified timeout). If the element is not found, an error is thrown which will cause the test to fail. You can suppress element not found errors by specifying the <code>selector</code> argument as an object and passing the <code>suppressNotFoundErrors = true</code> option.</p>\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('button.submit-form').doubleClick();\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('button.submit-form').doubleClick();\n *   }\n * }\n *\n * @since 3.0.0\n * @method doubleClick\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).doubleClick()\n * @see https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#double-click\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommand('doubleClick');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/dragAndDrop.js",
    "content": "/**\n * Drag an element to the given position or destination element.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element.find('.section').dragAndDrop({ x: 100, y: 100 });\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     // using destination coordinates\n *     browser.element.find('.section').dragAndDrop({ x: 0, y: 500 });\n *\n *     // using WebElement of destination\n *     const destWebElement = await browser.element.find('.dest-section');\n *     browser.element.find('.section').dragAndDrop(destWebElement);\n *   }\n * }\n *\n * @since 3.0.0\n * @method dragAndDrop\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).dragAndDrop({x, y})\n * @syntax browser.element(selector).dragAndDrop(<WebElement>)\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function(destination) {\n  return this.runQueuedCommand('dragElement', {\n    args: [destination]\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/find.js",
    "content": "/**\n * Search for an element on the page. The located element will be returned as a special web element object (with added convenience methods).\n * The argument is the element selector, either specified as a string or as an object (with 'selector' and 'locateStrategy' properties).\n * Elements can be searched by using another element as the starting point.\n * If many elements match the locating criteria, only first one is returned.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     // Using element function (alias for find).\n *     const button1 = browser.element('button.submit-form');\n *     // Using the find method of the element namespace.\n *     const button2 = browser.element.find('button.submit-form');\n *     // Searching for the icon element inside the .submit-form button.\n *     const icon = button2.find('i');\n *\n *     // Use an object to customise locating behaviour.\n *     const main = browser.element({ selector: 'main', locateStrategy: 'css selector' });\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     // button is the WebElement object.\n *     const button = await browser.element('button.submit-form');\n *   }\n * }\n *\n * @since 3.0.0\n * @method find\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.find(selector)\n * @param {String|Object} selector\n * @returns {ScopedWebElement}\n * @alias get\n * @alias findElement\n */\nmodule.exports.command = function(selector) {\n  return this.createScopedElement(selector, this);\n};\n\n"
  },
  {
    "path": "lib/api/web-element/commands/findAll.js",
    "content": "/**\n * Search for elements on the page. The located elements will be returned as a special web element object (with added convenience methods).\n * The argument is the element selector, either specified as a string or as an object (with 'selector' and 'locateStrategy' properties).\n * Elements can be searched by using another element as the starting point.\n *\n * @example\n * export default {\n *   async demoTest(browser: NightwatchAPI): Promise<void> {\n *     const buttonsElement = browser.element.findAll('button.submit-form');\n *\n *     // Get an array of found elements.\n *     const buttons = await buttonsElement;\n *\n *     // Use an object to customise locating behaviour.\n *     const sections = browser.element\n *       .findAll({ selector: 'section', locateStrategy: 'css selector' });\n *   }\n * }\n *\n * @since 3.0.0\n * @method findAll\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.findAll(syntax)\n * @param {Selector} selector\n * @returns {Array.<ScopeWebElement>}\n * @alias getAll\n * @alias findElements\n */\nmodule.exports.command = function(selector) {\n  return this.createScopedElements(selector, {parentElement: this, commandName: 'findAll'});\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/findAllByAltText.js",
    "content": "const {By} = require('selenium-webdriver');\n\n/**\n * Search for elements on the page that have the `alt` attribute with a specified text.\n * Elements can be searched by using another element as the starting point.\n * By default, provided text is treated as a substring, so for the `'foo'` will match `'foobar'` also.\n * If you need an exact comparison, provide the `{ exact: true }` as the second parameter.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     // Search by the substring matching.\n *     const images = browser.element.findAllByAltText('group of people');\n *\n *     // Search for the exact occurrence.\n *     const images = browser.element.findAllByAltText(\n *       'A group of people sitting in front of a computer.',\n *       { exact: true }\n *     );\n *   }\n * }\n *\n * @since 3.0.0\n * @method findAllByAltText\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.findAllByAltText(text, [options])\n * @param {string} text\n * @param {{exact: boolean}} [options]\n * @returns {Array.<ScopedWebElement>}\n */\nmodule.exports.command = function (text, {exact = true, ...options} = {}) {\n  const comparingModifier = exact ? '' : '*';\n\n  return this.findAll({\n    ...options,\n    selector: By.css(`[alt${comparingModifier}=\"${text}\"]`)\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/findAllByPlaceholderText.js",
    "content": "const {By} = require('selenium-webdriver');\n\n/**\n * Search for elements on the page that have the `placeholder` attribute with a specified text.\n * Elements can be searched by using another element as the starting point.\n * By default, provided text is treated as a substring, so for the `'foo'` will match `'foobar'` also.\n * If you need an exact comparison, provide the `{ exact: true }` as the second parameter.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     // Search by the substring matching.\n *     const inputs = browser.element.findAllByPlaceholderText('group of people');\n *\n *     // Search for the exact occurrence.\n *     const images = browser.element.findAllByPlaceholderText(\n *       'Search here',\n *       { exact: true }\n *     );\n *\n *     const images = browser.element.findAllByPlaceholderText(\n *       'Enter the number',\n *       { exact: true, suppressNotFoundError: true }\n *     );\n *   }\n * }\n *\n * @since 3.0.0\n * @method findAllByPlaceholderText\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.findAllByPlaceholderText(text, [options])\n * @param {string} text\n * @param { {exact: boolean, index: number, timeout: number, retryInterval: number, suppressNotFoundErrors: boolean} } [options]\n * @returns {Array.<ScopeWebElement>}\n */\nmodule.exports.command = function (text, {exact = true, ...options} = {}) {\n  const comparingModifier = exact ? '' : '*';\n\n  return this.findAll({\n    ...options,\n    selector: By.css(`[placeholder${comparingModifier}=\"${text}\"]`)\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/findAllByRole.js",
    "content": "const {By} = require('selenium-webdriver');\nconst {roles, roleElements} = require('aria-query');\n\n/**\n * Search for elements on the page that meet the provided ARIA role.\n * Elements can be searched by using another element as the starting point.\n *\n * You can pass some options to narrow the search:\n * - `selected` - picks elements that has the `area-selected` attribute with `true` or `false` value.\n * - `checked` - picks elements that has the `area-checked` attribute with `true` or `false` value.\n * - `pressed` - picks elements that has the `area-pressed` attribute with `true` or `false` value.\n * - `current` - picks elements that has the `area-current` attribute with `true` or `false` value.\n * - `level` - picks elements that has the `area-level` attribute with `true` or `false` value. This option is suitable only for the `heading` role.\n * - `expanded` - picks elements that has the `area-expanded` attribute with `true` or `false` value.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     const comboboxes = browser.element.findAllByRole('combobox');\n *\n *     const headings = browser.element.findAllByRole(\n *       'heading',\n *       { level: 2 }\n *     );\n *   }\n * }\n *\n * @since 3.0.0\n * @method findAllByRole\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.findAllByRole(role, [options])\n * @param {string} role\n * @param {{selected: boolean, checked: boolean, pressed: boolean, current: boolean, level: number, expanded: boolean}} [options]\n * @returns {Array.<ScopeWebElement>}\n */\nmodule.exports.command = function(role, {selected, checked, pressed, current, level, expanded, ...options} = {}) {\n  const roleInformation = roles.get(role);\n\n  if (!roleInformation) {\n    throw new Error(`The specified role \"${role}\" is unknown.`);\n  }\n\n  if (selected !== undefined) {\n    // guard against unknown roles\n    if (roleInformation.props['aria-selected'] === undefined) {\n      throw new Error(`\"aria-selected\" is not supported on role \"${role}\".`);\n    }\n  }\n\n  if (checked !== undefined) {\n    // guard against unknown roles\n    if (roleInformation.props['aria-checked'] === undefined) {\n      throw new Error(`\"aria-checked\" is not supported on role \"${role}\".`);\n    }\n  }\n\n  if (pressed !== undefined) {\n    // guard against unknown roles\n    if (roleInformation.props['aria-pressed'] === undefined) {\n      throw new Error(`\"aria-pressed\" is not supported on role \"${role}\".`);\n    }\n  }\n\n  if (current !== undefined) {\n    // guard against unknown roles\n    // All currently released ARIA versions support `aria-current` on all roles.\n    // Leaving this for symmetry and forward compatibility\n    if (roleInformation.props['aria-current'] === undefined) {\n      throw new Error(`\"aria-current\" is not supported on role \"${role}\".`);\n    }\n  }\n\n  if (level !== undefined) {\n    // guard against using `level` option with any role other than `heading`\n    if (role !== 'heading') {\n      throw new Error(`Role \"${role}\" cannot have \"level\" property.`);\n    }\n  }\n\n  if (expanded !== undefined) {\n    // guard against unknown roles\n    if (roleInformation.props['aria-expanded'] === undefined) {\n      throw new Error(`\"aria-expanded\" is not supported on role \"${role}\".`);\n    }\n  }\n\n  const explicitRoleSelector = `*[role~=\"${role}\"]`;\n  const roleRelations = roleElements.get(role) || new Set();\n  const implicitRoleSelectors = new Set(Array.from(roleRelations).map(({name}) => name));\n  const selector = By.css([explicitRoleSelector].concat(Array.from(implicitRoleSelectors)).join(','));\n\n  return this.createScopedElements({selector, ...options}, {parentElement: this, commandName: 'findAllByRole'});\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/findAllByText.js",
    "content": "const {By} = require('selenium-webdriver');\n\n/**\n * Search for elements on the page that contain a specified text.\n * Elements can be searched by using another element as the starting point.\n * By default, provided text is treated as a substring, so for the `'foo'` will match `'foobar'` also.\n * If you need an exact comparison, provide the `{ exact: true }` as the second parameter.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     // Search by the substring matching.\n *     const inputs = browser.element.findAllByText('group of people');\n *\n *     // Search for the exact occurrence.\n *     const images = browser.element.findAllByText(\n *       'The nostalgic office',\n *       { exact: true }\n *     );\n *   }\n * }\n *\n * @since 3.0.0\n * @method findAllByText\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.findAllByText(text, [options])\n * @param {string} text\n * @param {{exact: boolean}} [options]\n * @returns {Array.<ScopeWebElement>}\n */\nmodule.exports.command = function (text, {exact = true} = {}) {\n  const expr = exact ? `text()=\"${text}\"` : `contains(text(),\"${text}\")`;\n  const selector = By.xpath(`.//*[${expr}]`);\n\n  return this.createScopedElements({selector}, {parentElement: this, commandName: 'findAllByText'});\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/findByAltText.js",
    "content": "const {By} = require('selenium-webdriver');\n\n/**\n * Search for an element on the page that has the `alt` attribute with a specified text.\n * Element can be searched by using another element as the starting point.\n * By default, provided text is treated as a substring, so for the `'foo'` will match `'foobar'` also.\n * If you need an exact comparison, provide the `{ exact: true }` as the second parameter.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     // Search by the substring mathing.\n *     const image = browser.element.findByAltText('group of people');\n *\n *     // Search for the exact occurrence.\n *     const image = browser.element.findByAltText(\n *       'A group of people sitting in front of a computer.',\n *       { exact: true }\n *     );\n *   }\n * }\n *\n * @since 3.0.0\n * @method findByAltText\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.findByAltText(text, [options])\n * @param {string} text\n * @param {{exact: boolean}} [options]\n * @returns {Array.<ScopedWebElement>}\n */\nmodule.exports.command = function (text, {exact = true, ...options} = {}) {\n  const comparingModifier = exact ? '' : '*';\n\n  return this.find({\n    ...options,\n    selector: By.css(`[alt${comparingModifier}=\"${text}\"]`)\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/findByLabelText.js",
    "content": "const {By} = require('selenium-webdriver');\n\n/**\n * Search for the label that matches the given text, then find the element associated with that label.\n * Element can be searched by using another element as the starting point.\n * By default, provided text is treated as a substring, so for the `'foo'` will match `'foobar'` also.\n * If you need an exact comparison, provide the `{ exact: true }` as the second parameter.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     // Search by the substring matching.\n *     const image = browser.element.findByLabelText('dreamers');\n *\n *     // Search for the exact occurrence.\n *     const image = browser.element.findByLabelText(\n *       'A group of people sitting in front of a computer.',\n *       { exact: true }\n *     );\n *   }\n * }\n *\n * @since 3.0.0\n * @method findByLabelText\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.findByLabelText(text, [options])\n * @param {string} text\n * @param {{exact: boolean}} [options]\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function (text, {exact = true, timeout, retryInterval, suppressNotFoundErrors} = {}) {\n\n  const findByForId = async (instance, labelElement) => {\n    if (!labelElement) {\n      return null;\n    }\n\n    const forAttribute = await labelElement.getAttribute('for');\n\n    if (!forAttribute) {\n      return null;\n    }\n\n    const element = await instance.waitUntilElementsLocated({\n      selector: By.css(`input[id=\"${forAttribute}\"]`),\n      timeout,\n      retryInterval\n    });\n\n    return element;\n  };\n\n  const findByAriaLabelled = async (instance, labelWebElement) => {\n    if (!labelWebElement) {\n      return null;\n    }\n\n    const idAttribute = await labelWebElement.getAttribute('id');\n\n    if (!idAttribute) {\n      return null;\n    }\n\n    return instance.waitUntilElementsLocated({\n      selector: By.css(`input[aria-labelledby=\"${idAttribute}\"]`),\n      timeout,\n      retryInterval\n    });\n  };\n\n  const findByDirectNesting = async (labelWebElement) => {\n    if (!labelWebElement) {\n      return null;\n    }\n\n    try {\n      return await labelWebElement.findElement(By.css('input'));\n    } catch (err) {\n      return null;\n    }\n  };\n\n  const findByDeepNesting = async (text, {exact}) => {\n    const expr = exact ? `*[text()=\"${text}\"]` : `*[contains(text(), \"${text}\")]`;\n    const selector = By.xpath(`.//label[${expr}]`);\n\n    const labelElement = await this.find({\n      selector,\n      timeout,\n      retryInterval,\n      suppressNotFoundErrors: true\n    });\n\n    if (!labelElement) {\n      return null;\n    }\n\n    try {\n      return await labelElement.findElement(By.css('input'));\n    } catch (err) {\n      return null;\n    }\n  };\n\n  const findByAriaLabel = async (text, {exact}) => {\n    const labelElement = await this.find({\n      selector: By.css(`input[aria-label${exact ? '' : '*'}=\"${text}\"]`),\n      timeout,\n      retryInterval,\n      suppressNotFoundErrors: true\n    });\n\n    return labelElement;\n  };\n\n  const findFromLabel = async (instance, labelElement) => {\n    let element = null;\n\n    if (labelElement) {\n      try {\n        element = await findByForId(instance, labelElement);\n      } catch (err) {\n        // ignore\n      }\n\n      if (!element) {\n        try {\n          element = await findByAriaLabelled(instance, labelElement);\n        } catch (err) {\n          // ignore\n        }\n      }\n\n      if (!element) {\n        try {\n          element = await findByDirectNesting(labelElement);\n        } catch (err) {\n          // ignore\n        }\n      }\n    }\n\n    return element;\n  };\n\n  const createAction = function (labelElement) {\n    const instance = this;\n\n    return async function() {\n      const element = await findFromLabel(instance, labelElement);\n\n      if (element) {\n        return element;\n      }\n\n      const error = new Error(`The element associated with label whose text ${exact ? 'equals' : 'contains'} \"${text}\" has not been found.`);\n      if (!suppressNotFoundErrors) {\n        throw error;\n      }\n\n      return null;\n    };\n  };\n\n  const expr = exact ? `text()=\"${text}\"` : `contains(text(),\"${text}\")`;\n  const selector = By.xpath(`.//label[${expr}]`);\n\n  // eslint-disable-next-line no-async-promise-executor\n  return this.createScopedElement(new Promise(async (resolve, reject) => {\n    const labelElement = await this.find({\n      selector,\n      timeout,\n      retryInterval,\n      suppressNotFoundErrors: true\n    });\n\n    if (labelElement) {\n      const node = this.queueAction({name: 'findByLabelText', createAction: function () {\n        return createAction.call(this, labelElement);\n      }});\n\n      node.deferred.promise.then(resolve, reject);\n\n      return;\n    }\n\n    const byDeepNesting = await findByDeepNesting(text, {exact});\n    if (byDeepNesting) {\n      return resolve(byDeepNesting);\n    }\n\n    const byAriaLabel = await findByAriaLabel(text, {exact});\n    if (byAriaLabel) {\n      return resolve(byAriaLabel);\n    }\n\n    resolve(null);\n  }));\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/findByPlaceholderText.js",
    "content": "const {By} = require('selenium-webdriver');\n\n/**\n * Search for an element on the page that have the `placeholder` attribute with a specified text.\n * Element can be searched by using another element as the starting point.\n * By default, provided text is treated as a substring, so for the `'foo'` will match `'foobar'` also.\n * If you need an exact comparison, provide the `{ exact: true }` as the second parameter.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     // Search by the substring matching.\n *     const inputs = browser.element.findByPlaceholderText('group of people');\n *\n *     // Search for the exact occurrence.\n *     const images = browser.element.findByPlaceholderText(\n *       'Search here',\n *       { exact: true }\n *     );\n *\n *     const images = browser.element.findByPlaceholderText(\n *       'Enter the number',\n *       { exact: true, suppressNotFoundError: true }\n *     );\n *   }\n * }\n *\n * @since 3.0.0\n * @method findByPlaceholderText\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.findByPlaceholderText(text, [options])\n * @param {string} text\n * @param {{exact: boolean}} [options]\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function (text, {exact = true, ...options} = {}) {\n  const comparingModifier = exact ? '' : '*';\n\n  return this.find({\n    ...options,\n    selector: By.css(`[placeholder${comparingModifier}=\"${text}\"]`)\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/findByRole.js",
    "content": "/**\n * Search for an element on the page that meets the provided ARIA role.\n * Element can be searched by using another element as the starting point.\n *\n * You can pass some options to narrow the search:\n * - `selected` - picks an element that has the `area-selected` attribute with `true` or `false` value.\n * - `checked` - picks an element that has the `area-checked` attribute with `true` or `false` value.\n * - `pressed` - picks an element that has the `area-pressed` attribute with `true` or `false` value.\n * - `current` - picks an element that has the `area-current` attribute with `true` or `false` value.\n * - `level` - picks an element that has the `area-level` attribute with `true` or `false` value. This option is suitable only for the `heading` role.\n * - `expanded` - picks an element that has the `area-expanded` attribute with `true` or `false` value.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     const comboboxes = browser.element.findByRole('combobox');\n *\n *     const headings = browser.element.findByRole('heading', { level: 2 });\n *   }\n * }\n *\n * @since 3.0.0\n * @method findByRole\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.findByRole(role, [options])\n * @param {string} role\n * @param {{selected: boolean, checked: boolean, pressed: boolean, current: boolean, level: number, expanded: boolean}} [options]\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function(role, options) {\n  // eslint-disable-next-line no-async-promise-executor\n  return this.createScopedElement(new Promise(async (resolve, reject) => {\n    try {\n      const elements = await this.findAllByRole(role, options);\n      const element = elements[0];\n\n      if (!element) {\n        throw new Error(`The element with \"${role}\" role is not found.`);\n      }\n\n      resolve(element);\n    } catch (error) {\n      reject(error);\n    }\n  }), this);\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/findByText.js",
    "content": "const {By} = require('selenium-webdriver');\n\n/**\n * Search for an element on the page that contains a specified text.\n * Element can be searched by using another element as the starting point.\n * By default, provided text is treated as a substring, so for the `'foo'` will match `'foobar'` also.\n * If you need an exact comparison, provide the `{ exact: true }` as the second parameter.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     // Search by the substring matching.\n *     const inputs = browser.element.findByText('group of people');\n *\n *     // Search for the exact occurrence.\n *     const images = browser.element.findByText(\n *       'The nostalgic office',\n *       { exact: true }\n *     );\n *   }\n * }\n *\n * @since 3.0.0\n * @method findByText\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.findByText(text, [options])\n * @param {string} text\n * @param {{exact: boolean}} [options]\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function(text, {exact = true, ...options} = {}) {\n  const selector = exact\n    ? By.xpath(`.//*[text()=\"${text}\"]`)\n    : By.xpath(`.//*[contains(text(),\"${text}\")]`);\n\n  return this.find({\n    ...options,\n    selector\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getAccessibleName.js",
    "content": "/**\n * Returns the computed WAI-ARIA label of an element.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('*[name=\"search\"]')\n *       .getAccessibleName()\n *       .assert.valueEquals('Country calling code');\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const result: string = await browser.element('*[name=\"search\"]').getAccessibleName();\n *     console.log('getAccessibleName is ', result);\n *   }\n * }\n *\n * @since 3.0.0\n * @method getAccessibleName\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.find(selector).getAccessibleName()\n * @syntax browser.element.find(selector).getComputedLabel()\n * @link /#get-computed-label\n * @returns {ScopedValue<string>} A container with accessible name of an element.\n * @alias getComputedLabel\n */\nmodule.exports.command = function() {\n  return this.runQueuedCommandScoped('getElementAccessibleName');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getAriaRole.js",
    "content": "/**\n * Returns the computed WAI-ARIA role of an element.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('*[name=\"search\"]').getAriaRole()\n *       .assert.valueEquals('combobox');\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const result = await browser.element('*[name=\"search\"]').getAriaRole();\n *     console.log('getAriaRole result', result);\n *   }\n * }\n *\n * @since 3.0.0\n * @method getAriaRole\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.find(selector).getAriaRole()\n * @syntax browser.element.find(selector).getComputedRole()\n * @link /#get-computed-role\n * @returns {ScopedValue<string>} The container with computed WAI-ARIA role of an element.\n * @alias getComputedRole\n */\nmodule.exports.command = function() {\n  return this.runQueuedCommandScoped('getElementAriaRole');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getAttribute.js",
    "content": "/**\n * Retrieve the value of an attribute for a given DOM element.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding &amp; interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser\n *       .element('#main ul li a.first')\n *       .getAttribute('target')\n *       .assert.valueEquals('_blank');\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const result = await browser.element('#main ul li a.first').getAttribute('href');\n *     console.log('attribute', result);\n *   }\n * }\n *\n * @since 3.0.0\n * @method getAttribute\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).getAttribute(name)\n * @link /#get-element-attribute\n * @param {string} name The attribute name to inspect.\n * @returns {ScopedValue<string | null>} The value of the attribute\n */\nmodule.exports.command = function(name) {\n  return this.runQueuedCommandScoped('getElementValue', name);\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getCssProperty.js",
    "content": "/**\n * Retrieve the value of a CSS property for a given DOM element.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @tsexample\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('#main ul li a.first').getCssProperty('display')\n *       .assert.valueEquals('block');\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const result = await browser.element('#main ul li a.first').getCssProperty('display');\n *     console.log('display', result);\n *   }\n * }\n *\n * @example\n * export default {\n *   demoTest({ element }) {\n *     element('#main ul li a.first')\n *       .getCssProperty('display')\n *       .assert.valueEquals('block');\n *   },\n *\n *   async demoTestAsync({ element }) {\n *     const result = await element('#main ul li a.first').getCssProperty('display');\n *     console.log('display', result);\n *   }\n * }\n *\n * @since 3.0.0\n * @method getCssProperty\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).getCssProperty(name)\n * @link /#get-element-css-value\n * @param {string} cssProperty The CSS property to inspect.\n * @returns {ScopedValue<string>} The container with a value of the css property\n */\nmodule.exports.command = function(cssProperty) {\n  return this.runQueuedCommandScoped('getElementCSSValue', cssProperty);\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getFirstElementChild.js",
    "content": "/**\n * Returns an element's first child. The child element will be returned as web element JSON object (with an added .getId() convenience method).\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('.features-container').getFirstElementChild().then(resultElement => {\n *       console.log('first child element Id:', resultElement.getId());\n *     });\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const resultElement = await browser.element('.features-container').getFirstElementChild();\n *     console.log('first child element Id:', resultElement.getId());\n *   }\n * }\n *\n * @since 3.0.0\n * @method getFirstElementChild\n * @memberof ScopedWebElement\n * @instance\n * @tutorial developer.mozilla.org/en-US/docs/Web/API/Element/firstElementChild\n * @returns {ScopedWebElement}\n */\n\nmodule.exports.command = function() {\n  const createAction = (actions, webElement) => function getFirstElementChild() {\n    return actions.executeScript(function(element) {\n      return element.firstElementChild;\n    }, [webElement]);\n  };\n  const node = this.queueAction({name: 'getFirstElementChild', createAction});\n\n  return this.createScopedElement(node.deferred.promise);\n};\n\n"
  },
  {
    "path": "lib/api/web-element/commands/getId.js",
    "content": "/**\n * Returns the element ID\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     const elementId = browser.element('#main').getId();\n *     console.log('element id:', elementId)\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const elementId = await browser.element('#main').getId();\n *     console.log('element id:', elementId);\n *   },\n * }\n *\n * @since 3.0.0\n * @method getId\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).getId()\n * @returns {ScopedValue<string>}\n */\nmodule.exports.command = function() {\n  return this.runQueuedCommandScoped(function (webElement) {\n    return webElement.getId();\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getLastElementChild.js",
    "content": "/**\n * Returns an element's last child. The child element will be returned as web element JSON object (with an added .getId() convenience method).\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('.features-container').getLastElementChild().then(resultElement => {\n *       console.log('last child element Id:', resultElement.getId());\n *     });\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const resultElement = await browser.element('.features-container').getLastElementChild();\n *     console.log('last child element Id:', resultElement.getId());\n *   }\n * }\n *\n * @since 3.0.0\n * @method getLastElementChild\n * @memberof ScopedWebElement\n * @instance\n * @tutorial developer.mozilla.org/en-US/docs/Web/API/Element/lastElementChild\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function() {\n  const createAction = (actions, webElement) => function getLastElementChild() {\n    return actions.executeScript(function(element) {\n      return element.lastElementChild;\n    }, [webElement]);\n  };\n  const node = this.queueAction({name: 'getLastElementChild', createAction});\n\n  return this.createScopedElement(node.deferred.promise);\n};\n\n"
  },
  {
    "path": "lib/api/web-element/commands/getNextElementSibling.js",
    "content": "/**\n * Returns the element immediately following the specified one in their parent's childNodes. The element will be returned as web element JSON object (with an added .getId() convenience method).\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('.features-container li:first-child').getNextElementSibling().then(resultElement => {\n *       console.log('next sibling element Id:', resultElement.getId());\n *     });\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const resultElement = await browser.element('.features-container li:first-child').getNextElementSibling();\n *     console.log('next sibling element Id:', resultElement.getId());\n *   }\n * }\n *\n * @since 3.0.0\n * @method getNextElementSibling\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).getNextElementSibling()\n * @tutorial developer.mozilla.org/en-US/docs/Web/API/Element/nextElementSibling\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function() {\n  const createAction = (actions, webElement) => function() {\n    return actions.executeScript(function(element) {\n      return element.nextElementSibling;\n    }, [webElement]);\n  };\n  const node = this.queueAction({name: 'getNextElementSibling', createAction});\n\n  return this.createScopedElement(node.deferred.promise);\n};\n\n\n\n"
  },
  {
    "path": "lib/api/web-element/commands/getParentElement.js",
    "content": "/**\n * Returns an element's last child. The child element will be returned as web element JSON object (with an added .getId() convenience method).\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('.features-container').getParentElement().then(resultElement => {\n *       console.log('parent element Id:', resultElement.getId());\n *     });\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const resultElement = await browser.element('.features-container').getParentElement();\n *     console.log('parent element Id:', resultElement.getId());\n *   }\n * }\n *\n * @since 3.3.1\n * @method getParentElement\n * @memberof ScopedWebElement\n * @instance\n * @tutorial https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function() {\n  const createAction = (actions, webElement) => function getLastElementChild() {\n    return actions.executeScript(function(element) {\n      return element.parentElement;\n    }, [webElement]);\n  };\n  const node = this.queueAction({name: 'getParentElement', createAction});\n\n  return this.createScopedElement(node.deferred.promise);\n};\n\n"
  },
  {
    "path": "lib/api/web-element/commands/getPreviousElementSibling.js",
    "content": "/**\n * Returns the element immediately preceding the specified one in its parent's child elements list. The element will be returned as web element JSON object (with an added `.getId()` convenience method).\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('.features-container li:second-child').getPreviousElementSibling().then(resultElement => {\n *       console.log('previous sibling element Id:', resultElement.getId());\n *     });\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const resultElement = await browser.element('.features-container li:second-child').getPreviousElementSibling();\n *     console.log('previous sibling element Id:', resultElement.getId());\n *   }\n * }\n *\n * @since 3.0.0\n * @method getPreviousElementSibling\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).getPreviousElementSibling()\n * @tutorial developer.mozilla.org/en-US/docs/Web/API/Element/previousElementSibling\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function() {\n  const createAction = (actions, webElement) => function() {\n    return actions.executeScript(function(element) {\n      return element.previousElementSibling;\n    }, [webElement]);\n  };\n  const node = this.queueAction({name: 'getPreviousElementSibling', createAction});\n\n  return this.createScopedElement(node.deferred.promise);\n};\n\n\n\n"
  },
  {
    "path": "lib/api/web-element/commands/getProperty.js",
    "content": "/**\n * Retrieve the value of a specified DOM property for the given element. For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @tsexample\n * import { NightwatchBrowser } from 'nightwatch';\n *\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     const result = browser.element('#login input[type=text]').getProperty('classList');\n *     console.log('classList', result);\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const result = await browser.element('#login input[type=text]').getProperty('classList');\n *     console.log('classList', result);\n *   }\n * }\n *\n * @example\n * export default {\n *   demoTest(browser) {\n *     const result = browser.element('#login input[type=text]').getProperty('classList');\n *     console.log('classList', result);\n *   },\n *\n *   async demoTestAsync(browser) {\n *     const result = await browser.element('#login input[type=text]').getProperty('classList');\n *     console.log('classList', result);\n *   }\n * }\n *\n * @since 3.0.0\n * @method getProperty\n * @memberof ScopedWebElement\n * @param {string} name element property\n * @instance\n * @syntax browser.element(selector).getProperty(name)\n * @link /#get-element-property\n * @returns {ScopedValue<string>}\n */\nmodule.exports.command = function (name) {\n  return this.runQueuedCommandScoped('getElementProperty', name);\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getRect.js",
    "content": "/**\n * Determine an element's size in pixels.\n *\n * For W3C Webdriver compatible clients (such as GeckoDriver), this command is equivalent to `getLocation` and both return the dimensions and coordinates of the given element:\n * - x: X axis position of the top-left corner of the element, in CSS pixels\n * - y: Y axis position of the top-left corner of the element, in CSS pixels\n * - height: Height of the element’s bounding rectangle in CSS pixels;\n * - width: Width of the web element’s bounding rectangle in CSS pixels.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     const result = browser.element('#login').getRect();\n *     console.log('result', result);\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const result = await browser.element('#login').getRect();\n *     console.log('result', result);\n *   }\n * }\n *\n * @since 3.0.0\n * @method getRect\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).getRect()\n * @link /#dfn-get-element-rect\n * @returns {ScopedValue<{ width: number, height: number }>}\n * @alias getSize\n * @alias getLocation\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommandScoped('getElementRect');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getShadowRoot.js",
    "content": "/**\n * Returns the `shadowRoot` read-only property which represents the shadow root hosted by the element. This can further be used to retrieve elements part of the shadow root element.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('#login').getShadowRoot().then(result => {\n *       console.log('shadowRootEl', result);\n *     });\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const result = await browser.element('#login').getShadowRoot();\n *     console.log('shadowRootEl', result);\n *   }\n * }\n *\n * @since 3.0.0\n * @method getShadowRoot\n * @memberof ScopedWebElement\n * @instance\n * @tutorial developer.mozilla.org/en-US/docs/Web/API/Element/shadowRoot\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function() {\n  const createAction = (actions, webElement) => function() {\n    return actions.getShadowRoot(webElement);\n  };\n  const node = this.queueAction({name: 'getShadowRoot', createAction});\n\n  return this.createScopedElement(node.deferred.promise);\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getTagName.js",
    "content": "/**\n * Query for an element's tag name.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     const result = browser.element('#login').getTagName();\n *     console.log('element tag:', result);\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const result = await browser.element('#login').getTagName();\n *     console.log('element tag:', result);\n *   }\n * }\n *\n * @since 3.0.0\n * @method getTagName\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).getTagName()\n * @link /#get-element-tag-name\n * @returns {ScopedValue<string>}\n */\nmodule.exports.command = function() {\n  return this.runQueuedCommandScoped('getElementTagName');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getText.js",
    "content": "/**\n * Returns the visible text for the element.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('#main ul li a.first')\n *       .getText()\n *       .assert.contains('custom text');\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const result = await browser.element('#main ul li a.first').getText();\n *     console.log('element text:', result);\n *   }\n * }\n *\n * @since 3.0.0\n * @method getText\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).getText()\n * @link /#get-element-text\n * @returns {ScopedValue<string>}\n */\nmodule.exports.command = function() {\n  return this.runQueuedCommandScoped('getElementText');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/getValue.js",
    "content": "/**\n * Returns a form element current value.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     const result = browser.element('#login input[type=text]').getValue();\n *     console.log('Value', result);\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const result = await browser.element('#login input[type=text]').getValue();\n *     console.log('Value', result);\n *   }\n * }\n *\n * @since 3.0.0\n * @method getValue\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).getValue()\n * @link /#get-element-property\n * @returns {ScopedValue<string>}\n */\nmodule.exports.command = function () {\n  return this.getProperty('value');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/inspectInDevTools.js",
    "content": "/**\n * Inspect element in DevTools.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     const lastElement = browser.element('#nestedt').getLastElementChild().inspectInDevTools('lastChild');\n *     console.log('last element:', lastElement);\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const lastElement = await browser.element('#nestedt').getLastElementChild().inspectInDevTools('lastChild');\n *     console.log('last element:', lastElement);\n *   }\n * }\n *\n * @since 3.0.0\n * @method inspectInDevTools\n * @memberof ScopedWebElement\n * @param {string} txt\n * @instance\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function(txt) {\n  return this.runQueuedCommand('inspectInDevTools', {args: [txt]});\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/isActive.js",
    "content": "/**\n * Determines if an element is currently active/focused in the DOM.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n * For more info on the new `browser.element.find()` syntax, refer to the <a href=\"/api/element/\"> new Element API Overview </a> page.\n *\n * @example\n * describe('isActive Demo', function() {\n *   it('test isActive', function(browser) {\n *     browser.element.find('#search')\n *       .isActive()\n *       .assert.equals(true);\n *   });\n *\n *   it('test async isActive', async function(browser) {\n *     const result = await browser.element.find('#search').isActive();\n *     browser.assert.equal(result, true);\n *   });\n * });\n *\n * @since 3.9.0\n * @method isActive\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.find(selector).isActive()\n * @link /#get-active-element\n * @returns {ScopedValue<boolean>}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommandScoped('isElementActive');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/isEnabled.js",
    "content": "/**\n * Determines if an element is enabled.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n * For more info on the new `browser.element.find()` syntax, refer to the <a href=\"/api/element/\"> new Element API Overview </a> page.\n *\n * @example\n * describe('isEnabled Demo', function() {\n *   it('test isEnabled', function(browser) {\n *     browser.element.find('#search')\n *       .isEnabled()\n *       .assert.equals(true);\n *   });\n *\n *   it('test async isEnabled', async function(browser) {\n *     const result = await browser.element.find('#search').isEnabled();\n *     browser.assert.equal(result, true);\n *   });\n * });\n *\n * @since 3.5.0\n * @method isEnabled\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.find(selector).isEnabled()\n * @link /#is-element-enabled\n * @returns {ScopedValue<boolean>}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommandScoped('isElementEnabled');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/isPresent.js",
    "content": "/**\n * Checks if an element is present in the DOM.\n *\n * This command is useful for verifying the presence of elements that may/may not be visible or interactable.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n * For more info on the new `browser.element.find()` syntax, refer to the <a href=\"/api/element/\"> new Element API Overview </a> page.\n *\n * @example\n * describe('isPresent Demo', function() {\n *   it('test isPresent', function(browser) {\n *     browser.element.find('#search')\n *       .isPresent()\n *       .assert.equals(true);\n *   });\n *\n *   it('test async isPresent', async function(browser) {\n *     const result = await browser.element.find('#search').isPresent();\n *     browser.assert.equal(result, true);\n *   });\n * });\n *\n * @since 3.7.1\n * @method isPresent\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.find(selector).isPresent()\n * @returns {ScopedValue<boolean>} A boolean value indicating if the element is present in the DOM.\n */\n\nmodule.exports.command = function () {\n  return this.runQueuedCommandScoped('isElementPresent', {suppressNotFoundErrors: true});\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/isSelected.js",
    "content": "/**\n * Determines if an element is selected.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n * For more info on the new `browser.element.find()` syntax, refer to the <a href=\"/api/element/\"> new Element API Overview </a> page.\n *\n * @example\n * describe('isSelected Demo', function() {\n *   it('test isSelected', function(browser) {\n *     browser.element.find('#search')\n *       .isSelected()\n *       .assert.equals(true);\n *   });\n *\n *   it('test async isSelected', async function(browser) {\n *     const result = await browser.element.find('#search').isSelected();\n *     browser.assert.equal(result, true);\n *   });\n * });\n *\n * @since 3.5.0\n * @method isSelected\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.find(selector).isSelected()\n * @link /#is-element-selected\n * @returns {ScopedValue<boolean>}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommandScoped('isElementSelected');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/isVisible.js",
    "content": "/**\n * Determines if an element is visible.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n * For more info on the new `browser.element.find()` syntax, refer to the <a href=\"/api/element/\"> new Element API Overview </a> page.\n *\n *  @example\n * describe('isVisible demo', function() {\n *   it('test isVisible', function(browser) {\n *     browser.element.find('#search')\n *       .isVisible()\n *       .assert.equals(true);\n *   });\n *\n *   it('test async isVisible', async function(browser) {\n *     const result = await browser.element.find('#search').isVisible();\n *     browser.assert.equal(result, true);\n *   });\n * });\n *\n * @since 3.5.0\n * @method isVisible\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element.find(selector).isVisible()\n * @link /#element-displayedness\n * @returns {ScopedValue<boolean>}\n * @alias isDisplayed\n */\nmodule.exports.command = function() {\n  return this.runQueuedCommandScoped('isElementDisplayed');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/moveTo.js",
    "content": "/**\n * Move the mouse by an offset of the specified element. If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * <p class=\"alert alert-warning\">This command has been deprecated and is not available when using <a href=\"https://www.w3.org/TR/webdriver1/\">W3C Webdriver</a> clients (such as GeckoDriver). It's only available when using the Selenium <a href=\"https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol\" target=\"_blank\">JSONWire Protocol</a>.</p>\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('#main').moveTo(10, 10);\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('#main').moveTo(10, 10);\n *   }\n * }\n *\n * @since 3.0.0\n * @method moveTo\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).moveTo([x], [y])\n * @param {number} [x=0] X offset to move to, relative to the center of the element.\n * @param {number} [y=0] Y offset to move to, relative to the center of the element\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function(x = 0, y = 0) {\n  return this.runQueuedCommand('moveTo', {\n    args: [x, y]\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/rightClick.js",
    "content": "/**\n * Simulates a context-click(right click) event on the given DOM element. The element is scrolled into view if it is not already pointer-interactable. See the WebDriver specification for element [interactability](https://www.w3.org/TR/webdriver/#element-interactability).\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('#main ul li a.first').rightClick();\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('#main ul li a.first').rightClick();\n *   }\n * }\n *\n * @since 3.0.0\n * @method rightClick\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).rightClick()\n * @see https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#context-click\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommand('contextClick');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/sendKeys.js",
    "content": "/**\n * Types a key sequence on the DOM element. Can be used to send a sequence of key strokes to an element. Any UTF-8 character may be specified.\n *\n * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), is loaded onto the main Nightwatch instance as `browser.Keys`.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('input[type=text]').sendKeys('nightwatch');\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     browser.element('input[type=text]').sendKeys('nightwatch');\n *   }\n * }\n *\n * @since 3.0.0\n * @method sendKeys\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).sendKeys(...keys)\n * @param {...string} keys\n * @link /#element-send-keys\n * @see https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#sendKeys\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function (...args) {\n  const keys = args.reduce((prev, key) => {\n    const keyList = Array.isArray(key) ? key : [key];\n    prev.push(...keyList);\n\n    return prev;\n  }, []);\n\n  return this.runQueuedCommand('sendKeysToElement', {\n    args: [keys]\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/setAttribute.js",
    "content": "/**\n * Set the value of a specified DOM attribute for the given element. For all the available DOM attributes, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('#login input[type=text]').setAttribute('disabled', true);\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('#login input[type=text]').setAttribute('disabled', true);\n *   }\n * }\n *\n * @since 3.0.0\n * @method setAttribute\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).setAttribute(name, value)\n * @param {string} name The attribute name to set.\n * @param value The attribute value name to set.\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function(name, value) {\n  return this.runQueuedCommand('setElementAttribute', {\n    args: [name, value]\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/setProperty.js",
    "content": "/**\n * Set the value of a specified DOM property for the given element.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('#login').setProperty('title', 'Hello');\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('#login').setProperty('title', 'Hello');\n *   }\n * }\n *\n * @since 3.0.0\n * @method setProperty\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).setProperty(name, value)\n * @param {string} name The property name to set.\n * @param value The property value name to set.\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function(name, value) {\n  return this.runQueuedCommand('setElementProperty', {\n    args: [name, value]\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/setValue.js",
    "content": "/**\n * Sends some text to an element. Can be used to set the value of a form element or to send a sequence of key strokes to an element. Any UTF-8 character may be specified.\n *\n * <div class=\"alert alert-warning\"><strong>setValue</strong> also clears the existing value of the element by calling the <strong>clear()</strong> beforehand.</div>\n *\n * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), is loaded onto the main Nightwatch instance as `browser.Keys`.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n * @example\n * // send some simple text to an input\n * this.demoTest = function (browser) {\n *   const result = await browser.element('input[type=text]').setValue('nightwatch');\n * };\n *\n * // send some text to an input and hit enter.\n * this.demoTest = function (browser) {\n *   const result = await browser.element('input[type=text]').setValue(['nightwatch', browser.Keys.ENTER]);\n * };\n *\n *\n * @link /session/:sessionId/element/:id/value\n * @method setValue\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).setValue(inputValue)\n * @param {string|array} inputValue The text to send to the element or key strokes.\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @link https://www.w3.org/TR/webdriver#element-send-keys\n */\nmodule.exports.command = function(...args) {\n  const keys = args.reduce((prev, key) => {\n    const keyList = Array.isArray(key) ? key : [key];\n    prev.push(...keyList);\n\n    return prev;\n  }, []);\n\n  return this.runQueuedCommand('setElementValue', {\n    args: [keys]\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/submit.js",
    "content": "/**\n * Submits the form containing this element (or this element if it is itself a FORM element). his command is a no-op if the element is not contained in a form.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * <p class=\"alert alert-warning\">This command has been deprecated and is not available when using <a href=\"https://www.w3.org/TR/webdriver1/\">W3C Webdriver</a> clients (such as GeckoDriver). It's only available when using the Selenium <a href=\"https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol\" target=\"_blank\">JSONWire Protocol</a>.</p>\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('form.login').submit();\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('form.login').submit();\n *   }\n * }\n *\n * @since 3.0.0\n * @method submit\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).submit()\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function() {\n  return this.runQueuedCommand('elementSubmit');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/takeScreenshot.js",
    "content": "/**\n * Take a screenshot of the visible region encompassed by this element's bounding rectangle.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     const screenshot = browser.element('#main').takeScreenshot();\n *     screenshot.then((screenshotData) => {\n *       require('fs/promises').writeFile('out.png', screenshotData, 'base64');\n *     });\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     const screenshotData = await browser.element('#main').takeScreenshot();\n *     require('fs/promises').writeFile('out.png', screenshotData, 'base64');\n *   }\n * }\n *\n * @since 3.0.0\n * @method takeScreenshot\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).takeScreenshot()\n * @link /#dfn-take-element-screenshot\n * @returns {ScopedValue<string>}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommandScoped('takeElementScreenshot');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/uncheck.js",
    "content": "/**\n * Will uncheck, by clicking, on a checkbox or radio input if it is not already unchecked.\n * The element is scrolled into view if it is not already pointer-interactable. See the WebDriver specification for <a href=\"https://www.w3.org/TR/webdriver/#element-interactability\" target=\"_blank\">element interactability</a>.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('input[type=checkbox]:checked)').uncheck();\n *   },\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('input[type=checkbox]:checked)').uncheck();\n *   },\n * }\n *\n * @since 3.7.0\n * @method uncheck\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).uncheck()\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function () {\n  return this.runQueuedCommand('uncheckElement');\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/update.js",
    "content": "/**\n * Sends some text to an element. Can be used to set the value of a form element or to send a sequence of key strokes to an element. Any UTF-8 character may be specified.\n *\n * <div class=\"alert alert-warning\"><strong>update</strong> also clears the existing value of the element by calling the <strong>clear()</strong> beforehand.</div>\n *\n * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), is loaded onto the main Nightwatch instance as `browser.Keys`.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('input[type=text]').update('nightwatch', browser.Keys.ENTER);\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('input[type=text]').update('nightwatch', browser.Keys.ENTER);\n *   }\n * }\n *\n * @since 3.0.0\n * @method update\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).update(characters, ...keys)\n * @param {...string} keys\n * @link /#element-send-keys\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function (...args) {\n  const keys = args.reduce((prev, key) => {\n    const keyList = Array.isArray(key) ? key : [key];\n    prev.push(...keyList);\n\n    return prev;\n  }, []);\n\n  return this.runQueuedCommand('setElementValue', {\n    args: [keys]\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/commands/upload.js",
    "content": "/**\n * Uploads file to an element using absolute file path.\n *\n * For more info on working with DOM elements in Nightwatch, refer to the <a href=\"https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html\">Finding & interacting with DOM Elements</a> guide page.\n *\n * @example\n * export default {\n *   demoTest(browser: NightwatchAPI): void {\n *     browser.element('#myFile').upload('/path/file.pdf');\n *   },\n *\n *   async demoTestAsync(browser: NightwatchAPI): Promise<void> {\n *     await browser.element('#myFile').upload('/path/file.pdf');\n *   }\n * }\n *\n * @since 3.0.0\n * @method upload\n * @memberof ScopedWebElement\n * @instance\n * @syntax browser.element(selector).upload(filePath)\n * @param {string} file The file path to upload.\n * @tutorial www.selenium.dev/documentation/en/remote_webdriver/remote_webdriver_client/\n * @returns {ScopedWebElement}\n */\nmodule.exports.command = function(file) {\n  return this.runQueuedCommand('uploadFile', {\n    args: [file]\n  });\n};\n"
  },
  {
    "path": "lib/api/web-element/element-locator.js",
    "content": "const {By, RelativeBy} = require('selenium-webdriver');\n\nconst Utils = require('../../utils');\nconst Element = require('../../element/index.js');\nconst Locator = require('../../element/locator.js');\nconst NightwatchLocator = require('../../element/locator-factory');\n\nclass ElementLocator {\n  constructor(selector, options = {}) {\n    this.index = ElementLocator.getOrDefault(selector, ['index', '__index'], 0);\n    this.timeout = ElementLocator.getOrDefault(selector, 'timeout', options.waitForConditionTimeout);\n    this.retryInterval = ElementLocator.getOrDefault(selector, 'retryInterval', options.waitForConditionPollInterval);\n    this.locateStrategy = ElementLocator.getLocateStrategy(selector, options.locateStrategy);\n    this.abortOnFailure = ElementLocator.getOrDefault(selector, 'abortOnFailure', true);\n    this.suppressNotFoundErrors = ElementLocator.getOrDefault(selector, 'suppressNotFoundErrors', false);\n    this.condition = ElementLocator.getCondition(selector, this.locateStrategy);\n  }\n\n  static create(selector, nightwatchInstance = {}) {\n    return new ElementLocator(selector, {\n      waitForConditionTimeout: nightwatchInstance.settings.globals.waitForConditionTimeout,\n      waitForConditionPollInterval: nightwatchInstance.settings.globals.waitForConditionPollInterval,\n      locateStrategy: nightwatchInstance.locateStrategy\n    });\n  }\n\n  static getOrDefault(obj, props, defaultValue) {\n    if (!Utils.isObject(obj)) {\n      return defaultValue;\n    }\n\n    const propArray = Array.isArray(props) ? props : [props];\n\n    for (const prop of propArray) {\n      // eslint-disable-next-line no-prototype-builtins\n      if (obj.hasOwnProperty(prop) && Utils.isDefined(obj[prop])) {\n        return obj[prop];\n      }\n    }\n\n    return defaultValue;\n  }\n\n  static getLocateStrategy(element, strategy) {\n    if (element instanceof By) {\n      return element.using;\n    }\n\n    if (Utils.isString(element)) {\n      return strategy;\n    }\n\n    return ElementLocator.getOrDefault(element, 'locateStrategy', strategy);\n  }\n\n  static isElementDescriptor(selector) {\n    if (!Utils.isObject(selector)) {\n      return false;\n    }\n\n    if (selector.__nightwatchScopedWebElement__) {\n      return true;\n    }\n\n    // eslint-disable-next-line no-prototype-builtins\n    return ['selector', 'xpath', 'css'].some(prop => selector.hasOwnProperty(prop));\n  }\n\n  static getSelectorValue(descriptor) {\n    if (descriptor.selector instanceof By || descriptor.selector instanceof RelativeBy) {\n      return descriptor.selector;\n    }\n\n    if (descriptor.xpath) {\n      return By.xpath(descriptor.xpath);\n    }\n\n    if (descriptor.css) {\n      return By.css(descriptor.css);\n    }\n\n    return null;\n  }\n\n  static getCondition(element, strategy) {\n    const locateStrategy = ElementLocator.getLocateStrategy(element, strategy);\n\n    if (element instanceof By || element instanceof RelativeBy) {\n      return element;\n    }\n\n    if (element instanceof Element) {\n      if (element.usingRecursion) {\n        return element;\n      }\n\n      return NightwatchLocator.create(element);\n    }\n\n    if (!ElementLocator.isElementDescriptor(element)) {\n      return By[Locator.AVAILABLE_LOCATORS[locateStrategy]](element);\n    }\n\n    const selector = ElementLocator.getSelectorValue(element);\n    if (selector) {\n      return selector;\n    }\n\n    return By[Locator.AVAILABLE_LOCATORS[locateStrategy]](element.selector);\n  }\n}\n\nmodule.exports.ScopedElementLocator = ElementLocator;\n"
  },
  {
    "path": "lib/api/web-element/element-value.js",
    "content": "module.exports.create = function createScopedValue(value, nightwatchInstance) {\n\n  class ScopedValue {\n    constructor(value) {\n      this.value = Promise.resolve(value);\n    }\n\n    then(onFulfilled, onRejected) {\n      return this.value.then(onFulfilled, onRejected);\n    }\n\n    map(callback) {\n      return createScopedValue(this.then(callback), nightwatchInstance);\n    }\n  }\n\n  return new ScopedValue(value);\n};\n\n"
  },
  {
    "path": "lib/api/web-element/factory.js",
    "content": "const ScopedWebElements = require('./scoped-elements.js');\nconst ScopedWebElement = require('./scoped-element.js');\nconst ScopedElementAssertions = require('./assert/element-assertions.js');\nconst WaitUntil = require('./waitUntil.js');\n\nconst Element = require('../../element');\nconst ScopedValueAssertions = require('./assert/value-assertions.js');\nconst ScopedValue = require('./element-value.js');\n\nconst throwError = (message, commandName) => {\n  const error = new Error(`Error in ${commandName}(): ${message}`);\n\n  return error;\n};\n\nconst createScopedWebElement = function(selector, parentElement, nightwatchInstance) {\n  const instance = new ScopedWebElement(selector, parentElement, nightwatchInstance);\n  const exported = selector ? Element.createFromSelector(selector) : {};\n\n  const methodNames = ScopedWebElement.getMethodNames();\n  methodNames.forEach(({commandName: methodName, originalCommandName}) => {\n    const fn = {\n      [methodName]: function(...args) {\n        return instance.executeMethod(exported, originalCommandName || methodName, ...args);\n      }\n    };\n\n    Object.defineProperty(exported, methodName, {\n      value: fn[methodName],\n      writable: false,\n      enumerable: !originalCommandName,\n      configurable: true\n    });\n  });\n\n  Object.defineProperty(exported, 'assert', {\n    get() {\n      return ScopedElementAssertions.create(instance, {\n        negated: false,\n        nightwatchInstance\n      });\n    },\n    enumerable: true,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'waitUntil', {\n    value(actionOrOptions, opts = {}) {\n      return createScopedWebElement(new Promise(function (resolve, reject) {\n        const args = Object.assign({}, opts);\n\n        if (typeof actionOrOptions === 'string') {\n          args.action = actionOrOptions;\n        } else if (actionOrOptions && typeof actionOrOptions === 'object') {\n          Object.assign(args, actionOrOptions);\n        }\n\n        const waitUntil = new WaitUntil(instance, {\n          selector,\n          nightwatchInstance,\n          ...args\n        });\n\n        return waitUntil.wait().then(element => resolve(element));\n      }.bind(instance)), parentElement, nightwatchInstance);\n    }\n\n  });\n\n  Object.defineProperty(exported, 'then', {\n    value(onFulfilled, onRejected) {\n      return instance.then(onFulfilled, onRejected);\n    },\n    enumerable: true,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'webElement', {\n    get() {\n      return instance.webElement;\n    },\n    enumerable: true,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'runQueuedCommand', {\n    value(...args) {\n      return instance.runQueuedCommand(...args);\n    },\n    enumerable: false,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'createRootElementCommand', {\n    value(...args) {\n      return instance.createRootElementCommand(...args);\n    },\n    enumerable: false,\n    configurable: false\n  });\n\n  Object.defineProperty(exported, 'runQueuedCommandScoped', {\n    value(commandName, ...args) {\n      const node = instance.createNode(commandName, args);\n\n      return createScopedValue(node, nightwatchInstance);\n    },\n    enumerable: false,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'queueAction', {\n    get() {\n      return instance.queueAction.bind(instance);\n    },\n    enumerable: false,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'createScopedElement', {\n    value(selector, parentElement = false) {\n      return createScopedWebElement.call(\n        instance,\n        selector,\n        parentElement ? parentElement : null,\n        instance.nightwatchInstance\n      );\n    },\n    enumerable: false,\n    configurable: false\n  });\n\n  Object.defineProperty(exported, 'createScopedElements', {\n    value(selector, {commandName, parentElement = false} = {}) {\n      return createScopedWebElements.call(instance, commandName, selector, parentElement ? parentElement : null, instance.nightwatchInstance);\n    },\n    enumerable: false,\n    configurable: false\n  });\n\n  return exported;\n};\n\nconst createScopedWebElements = function(commandName, selector, parentElement, nightwatchInstance) {\n  const instance = new ScopedWebElements(selector, parentElement, nightwatchInstance);\n  const createAction = () => function({args}) {\n    const elms = args[0];\n\n    return elms.then(elements => elements.map(el => createScopedWebElement(el, parentElement, nightwatchInstance)));\n  };\n\n  const node = this.queueAction({name: commandName, args: [instance], createAction, namespace: 'element'});\n  node.printArgs = function() {\n    return `{ ${selector} }`;\n  };\n\n  const exported = {};\n\n  Object.defineProperty(exported, 'then', {\n    value(onFulfilled, onRejected) {\n      return instance.then(onFulfilled, onRejected);\n    },\n    enumerable: false,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'count', {\n    value() {\n      return createScopedValue({\n        deferred: {\n          promise: instance.then((elements) => elements.length)\n        }\n      }, nightwatchInstance);\n    },\n    enumerable: true,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'nth', {\n    value(index = 0) {\n      return createScopedWebElement(new Promise(function (resolve, reject) {\n        this.then((elements) => {\n          if (elements.length === 0) {\n            return reject(throwError(`No elements found for selector: ${selector}`, 'nth'));\n          }\n\n          if (index < 0 || index >= elements.length) {\n            return reject(throwError(`Index ${index} out of bounds for selector: ${selector}`, 'nth'));\n          }\n\n          resolve(elements[index]);\n        });\n      }.bind(instance)), parentElement, nightwatchInstance);\n    },\n    enumerable: true,\n    configurable: true\n  });\n\n  // Object.defineProperty(exported, 'assert', {\n  //   get() {\n  //     return new ScopedElementsAssertions(instance, {\n  //       negated: false,\n  //       nightwatchInstance\n  //     });\n  //   },\n  //   enumerable: false,\n  //   configurable: true\n  // });\n\n  return exported;\n};\n\nconst createScopedValue = function(node, nightwatchInstance) {\n  const instance = ScopedValue.create(node.deferred.promise, nightwatchInstance);\n  const exported = {};\n\n  Object.defineProperty(exported, 'then', {\n    value(onFulfilled, onRejected) {\n      return instance.then(onFulfilled, onRejected);\n    },\n    enumerable: true,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'map', {\n    value(callback) {\n      return instance.map(callback);\n    },\n    enumerable: true,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'assert', {\n    get() {\n      return ScopedValueAssertions.create(instance, {\n        negated: false,\n        nightwatchInstance\n      });\n    },\n    enumerable: true,\n    configurable: true\n  });\n\n  Object.defineProperty(exported, 'value', {\n    get() {\n      return instance.value;\n    },\n    enumerable: true,\n    configurable: false\n  });\n\n  return exported;\n};\n\nmodule.exports.createScopedWebElements = createScopedWebElements;\nmodule.exports.create = createScopedWebElement;\nmodule.exports.createScopedValue = createScopedValue;\n"
  },
  {
    "path": "lib/api/web-element/index.js",
    "content": "const {WebElement} = require('selenium-webdriver');\nconst Factory = require('./factory.js');\n\nmodule.exports.active = function(nightwatchInstance) {\n  const {transportActions} = nightwatchInstance;\n  const node = nightwatchInstance.queue.add(function findActiveElement() {\n    return transportActions.getActiveElement();\n  });\n\n  const instance = new WebElement(nightwatchInstance.transport.driver, node.deferred.promise);\n\n  return Factory.create(instance, null, nightwatchInstance);\n};\n\nmodule.exports.root = function(nightwatchInstance) {\n  return Factory.create(null, null, nightwatchInstance);\n};\n\nmodule.exports.createScopedWebElements = Factory.createScopedWebElements;\nmodule.exports.create = Factory.create;\n"
  },
  {
    "path": "lib/api/web-element/scoped-element.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst {until, WebElement, WebElementPromise, Condition} = require('selenium-webdriver');\nconst {ShadowRoot} = require('selenium-webdriver/lib/webdriver');\n\nconst {Logger, isFunction, createPromise} = require('../../utils/');\nconst {WEB_ELEMENT_ID} = require('../../transport/selenium-webdriver/session.js');\nconst {ScopedElementLocator} = require('./element-locator.js');\n\nclass ScopedWebElement {\n\n  static get methodAliases() {\n    return {\n      'find': ['findElement', 'get'],\n      'findAll': ['findElements', 'getAll'],\n      'findByText': ['getByText'],\n      'findByRole': ['getByRole'],\n      'findByPlaceholderText': ['getByPlaceholderText'],\n      'findByLabelText': ['getByLabelText'],\n      'findByAltText': ['getByAltText'],\n      'findAllByText': ['getAllByText'],\n      'findAllByRole': ['getAllByRole'],\n      'findAllByPlaceholderText': ['getAllByPlaceholderText'],\n      'findAllByAltText': ['getAllByAltText'],\n      'getRect': ['getSize', 'getLocation', 'rect'],\n      'getAttribute': ['attr', 'attribute'],\n      'getProperty': ['property', 'prop'],\n      'getText': ['text'],\n      'getTagName': ['tagName'],\n      'getAccessibleName': ['accessibleName', 'getComputedLabel'],\n      'getCssProperty': ['css', 'getCssValue'],\n      'getAriaRole': ['ariaRole', 'getComputedRole'],\n      'isVisible': ['isDisplayed']\n    };\n  }\n\n  static getMethodNames() {\n    const methodsDir = path.resolve(__dirname, 'commands');\n    const methodFiles = fs.readdirSync(methodsDir);\n\n    return methodFiles\n      .map(fileName => path.parse(fileName).name)\n      .flatMap(commandName => {\n        const aliases = ScopedWebElement.methodAliases[commandName];\n\n        const commandNames = [{commandName}];\n\n        if (aliases) {\n          commandNames.push(...aliases.map(commandNameAlias => ({commandName: commandNameAlias, originalCommandName: commandName})));\n        }\n\n        return commandNames;\n      })\n      .filter(({commandName: fileName}) => !fileName.startsWith('_'));\n  }\n\n  get driver() {\n    return this.nightwatchInstance.transport.driver;\n  }\n\n  get reporter() {\n    return this.nightwatchInstance.reporter;\n  }\n\n  get queue() {\n    return this.nightwatchInstance.queue;\n  }\n\n  get __nightwatchScopedWebElement__() {\n    return true;\n  }\n\n  get suppressNotFoundErrors() {\n    return this._suppressNotFoundErrors;\n  }\n\n  constructor(selector = 'html', parentElement, nightwatchInstance) {\n    this.nightwatchInstance = nightwatchInstance;\n    this.parentScopedElement = parentElement;\n\n    this.webElement = this.createWebElementPromise({\n      selector,\n      parentElement\n    });\n  }\n\n  async waitUntilElementsLocated(selector) {\n    const {timeout, condition, retryInterval} = ScopedElementLocator.create(selector, this.nightwatchInstance);\n    const webElements = await this.driver.wait(until.elementsLocated(condition), timeout, null, retryInterval);\n\n    if (webElements.length === 0) {\n      return null;\n    }\n\n    return webElements[0];\n  }\n\n  async locateElements({parentElement, selector, timeout, retryInterval}) {\n    const createLocateElement = () => {\n      return parentElement && parentElement.webElement ? function(locator) {\n        return new Condition('for at least one element to be located ' + locator, function (driver) {\n          return parentElement.webElement\n            .then(function (webElement) {\n              // also takes into consideration if `webElement`\n              // resolves to a shadow root.\n              return webElement.findElements(locator);\n            })\n            .then(function (elements) {\n              return elements.length > 0 ? elements : null;\n            });\n        });\n      } : until.elementsLocated;\n    };\n\n    const locateFn = createLocateElement();\n    const webElements = await this.driver.wait(locateFn(selector), timeout, null, retryInterval);\n\n    return webElements;\n  }\n\n  async findElementUsingRecursion({parentElement, recursiveElement, timeout, retryInterval}) {\n    const allElements = Array.isArray(recursiveElement.selector) ? recursiveElement.selector.slice() : [\n      recursiveElement\n    ];\n\n    let result = null;\n    while (allElements.length > 0) {\n      const nextElement = allElements.shift();\n      if (result) {\n        parentElement = {webElement: Promise.resolve(result)};\n      }\n\n      const {condition, index} = ScopedElementLocator.create(nextElement, this.nightwatchInstance);\n      result = await this.findElement({parentElement, selector: condition, index, timeout, retryInterval});\n\n      if (!result) {\n        break;\n      }\n    }\n\n    return result;\n  }\n\n  async findElement({parentElement, selector, index, timeout, retryInterval}) {\n    const webElements = await this.locateElements({parentElement, selector, timeout, retryInterval});\n\n    if (webElements.length === 0) {\n      const err = new Error(`Cannot find element with \"${selector}\" selector in ${timeout} milliseconds.`);\n      this.reporter.registerTestError(err);\n\n      return;\n    }\n\n    if (index > webElements.length) {\n      const err = new Error(`The index \"${index}\" is out of bounds for selector \"${selector}\".`);\n      this.reporter.registerTestError(err);\n\n      return;\n    }\n\n    return webElements[index];\n  }\n\n  async findElementAction({parentElement, condition, index, timeout, retryInterval, abortOnFailure}) {\n    const createAction = () => async ({args}) => {\n      if ((args[0] instanceof Promise) && !args[0]['@nightwatch_element']) {\n        args[0] = await args[0];\n      }\n\n      const parentElement = args[0];\n\n      if (parentElement?.webElement && await parentElement.webElement === null) {\n        return null;\n      }\n\n      try {\n        if (condition.usingRecursion) {\n          return await this.findElementUsingRecursion({parentElement, recursiveElement: condition, timeout, retryInterval});\n        }\n\n        return await this.findElement({parentElement, selector: condition, index, timeout, retryInterval});\n      } catch (error) {\n        const narrowedError = createNarrowedError({error, condition, timeout});\n        if (\n          this.suppressNotFoundErrors &&\n          narrowedError.name === 'NoSuchElementError'\n        ) {\n          return null;\n        }\n\n        Logger.error(narrowedError);\n\n        if (abortOnFailure) {\n          this.reporter.registerTestError(narrowedError);\n          // TODO: find a way to reject here without unhandled promise rejection\n          // reject(narrowedError);\n        }\n\n        return null;\n      }\n    };\n\n    const node = this.queueAction({name: 'find', createAction, namespace: 'element', args: [parentElement]});\n\n    node.printArgs = function() {\n      if (condition.selector) {\n        return `{ ${condition.selector} }`;\n      }\n\n      return `{ ${condition} }`;\n    };\n\n    return node.deferred.promise;\n  }\n\n  createWebElementPromise({selector, parentElement}) {\n    if (!selector) {\n      return null;\n    }\n\n    // eslint-disable-next-line no-async-promise-executor\n    return new WebElementPromise(this.driver, new Promise(async (resolve, reject) => {\n      if (selector instanceof Promise) {\n        try {\n          selector = await selector;\n        } catch (error) {\n          return reject(error);\n        }\n      }\n\n      if (!selector) {\n        return resolve(null);\n      }\n\n      if (selector instanceof WebElement) {\n        return resolve(selector);\n      }\n\n      if (selector instanceof ShadowRoot) {\n        return resolve(selector);\n      }\n\n      if (selector[WEB_ELEMENT_ID] && isFunction(selector.getId)) {\n        const webElement = new WebElement(this.driver, selector.getId());\n\n        return resolve(webElement);\n      }\n\n\n      const {index, timeout, condition, retryInterval, abortOnFailure, suppressNotFoundErrors} = ScopedElementLocator.create(selector, this.nightwatchInstance);\n      if (condition instanceof WebElement || condition instanceof WebElementPromise) {\n        return resolve(condition);\n      }\n\n      if (suppressNotFoundErrors) {\n        this._suppressNotFoundErrors = true;\n      }\n\n      const webElement = await this.findElementAction({\n        parentElement, condition, index, timeout, retryInterval, abortOnFailure\n      });\n\n      resolve(webElement);\n    }));\n  }\n\n  /**\n   * Keeps in sync operation sequence produced by methods.\n   */\n  waitFor(promise, {isRoot = false} = {}) {\n    if (isRoot) {\n      this.webElement = promise;\n    } else {\n      this.webElement = new WebElementPromise(this.driver, this.then(async (element) => {\n        await promise;\n\n        return element;\n      }));\n    }\n\n    return this;\n  }\n\n  createRootElementCommand(name, context, args) {\n    const result = context[name](...args, {isRoot: true});\n\n    return result;\n  }\n\n  createNode(commandName, args) {\n    if (args[0]?.suppressNotFoundErrors) {\n      this._suppressNotFoundErrors = true;\n    }\n\n    const createAction = (actions, webElement) => function () {\n      if (isFunction(commandName)) {\n        return commandName(webElement, ...args);\n      }\n\n      return actions[commandName](webElement, ...args);\n    };\n\n    const node = this.queueAction({name: commandName, createAction});\n\n    // TODO: check what changes if we keep the original `getResult` instead of below.\n    node.getResult = function(result) {\n      // here, we resolve the node with `result.value` even if the result contains an error and status === -1\n      // which results in the command result to be `null` in test case as well, while the command actually failed.\n      // Is this expected? To return `null` result in case of failure as well?\n      // eslint-disable-next-line no-prototype-builtins\n      return result.hasOwnProperty('value') ? result.value : result;\n    };\n\n    return node;\n  }\n\n  runQueuedCommand(commandName, {args = [], namespace, isRoot = false, name} = {}) {\n    const node = this.createNode(commandName, args, namespace);\n\n    if (name) {\n      node.name = name;\n    }\n\n    return this.waitFor(node.deferred.promise, {isRoot});\n  }\n\n  queueAction({name, createAction, namespace = 'element()', args = [], rejectPromise = true} = {}) {\n    const opts = {\n      args,\n      context: null,\n      deferred: createPromise(),\n      commandFn: createAction.call(this, this.nightwatchInstance.transportActions, this.webElement),\n      namespace,\n      rejectPromise,\n      commandName: name\n    };\n\n    return this.queue.add(opts);\n  }\n\n  executeMethod(context, methodName, ...args) {\n    const methodPath = path.resolve(__dirname, 'commands', `${methodName}.js`);\n    const methodFunc = require(methodPath);\n\n    return methodFunc.command.call(context, ...args);\n  }\n\n\n  then(onFulfilled, onRejected) {\n    return this.webElement.then(onFulfilled, onRejected);\n  }\n}\n\nfunction createNarrowedError({error, condition, timeout}) {\n  if (error.name === 'TimeoutError') {\n    const err = new Error(`Timed out while waiting for element \"${condition}\" to be present for ${timeout} milliseconds.`);\n    err.name = 'NoSuchElementError';\n\n    return err;\n  }\n\n  error.message = `Error occurred while trying to locate element \"${condition}\": ${error.message || 'unknown error'}`;\n\n  return error;\n}\n\nmodule.exports = ScopedWebElement;\n"
  },
  {
    "path": "lib/api/web-element/scoped-elements.js",
    "content": "const {until} = require('selenium-webdriver');\n\nconst {Logger, createPromise} = require('../../utils');\nconst {ScopedElementLocator} = require('./element-locator.js');\n\nclass ScopedElements {\n  constructor(selector, parentScopedElement, nightwatchInstance) {\n    this.parentScopedElement = parentScopedElement;\n    this.nightwatchInstance = nightwatchInstance;\n\n    // eslint-disable-next-line no-async-promise-executor\n    this.webElements = new Promise(async (resolve, reject) => {\n      if (selector instanceof Promise) {\n        try {\n          selector = await selector;\n        } catch (error) {\n          return reject(error);\n        }\n      }\n      if (Array.isArray(selector)) {\n        resolve(selector);\n      } else {\n        try {\n          const webElements = await this.findElementsAction(selector);\n\n          resolve(webElements);\n        } catch (error) {\n          resolve([]);\n        }\n      }\n    });\n  }\n\n  async findElementsUsingRecursion({parentElement, recursiveElement, timeout, retryInterval}) {\n    const allElements = Array.isArray(recursiveElement.selector) ? recursiveElement.selector.slice() : [\n      recursiveElement\n    ];\n\n    let result = [];\n    while (allElements.length > 0) {\n      const nextElement = allElements.shift();\n      if (result.length) {\n        parentElement = {webElement: result[0]};\n      }\n\n      const {condition} = ScopedElementLocator.create(nextElement, this.nightwatchInstance);\n      result = await this.findElements({parentElement, selector: condition, timeout, retryInterval});\n\n      if (!result || result.length === 0) {\n        result = [];\n        break;\n      }\n    }\n\n    return result;\n  }\n\n  async findElements({parentElement, selector, timeout, retryInterval}) {\n    let webElements;\n\n    if (parentElement && parentElement.webElement) {\n      const parentWebElement = await parentElement.webElement;\n      webElements = await parentWebElement.findElements(selector);\n    } else {\n      webElements = await this.nightwatchInstance.transport.driver.wait(until.elementsLocated(selector), timeout,  null, retryInterval);\n    }\n\n    return webElements;\n  }\n\n  async findElementsAction(descriptor) {\n    const {\n      timeout,\n      condition,\n      retryInterval,\n      abortOnFailure,\n      suppressNotFoundErrors\n    } = ScopedElementLocator.create(descriptor, this.nightwatchInstance);\n\n    const commandFn = async ({args}) => {\n      const parentElement = args[0];\n\n      try {\n        if (condition.usingRecursion) {\n          return await this.findElementsUsingRecursion({parentElement, recursiveElement: condition, timeout, retryInterval});\n        }\n\n        return await this.findElements({parentElement, selector: condition, timeout, retryInterval});\n      } catch (error) {\n        if (suppressNotFoundErrors) {\n          return [];\n        }\n\n        const narrowedError = error.name === 'TimeoutError'\n          ? new Error(`No elements with selector \"${condition}\" found for ${timeout} milliseconds.`)\n          : error;\n\n        Logger.error(narrowedError);\n\n        if (abortOnFailure) {\n          this.nightwatchInstance.reporter.registerTestError(narrowedError);\n\n          throw narrowedError;\n        }\n\n        return [];\n      }\n    };\n\n    const node = this.queueAction({name: 'findAll', commandFn, namespace: 'element', args: [this.parentScopedElement]});\n    node.printArgs = function() {\n      if (descriptor.selector) {\n        return `{ ${descriptor.selector} }`;\n      }\n\n      return `{ ${descriptor} }`;\n    };\n\n    return node.deferred.promise;\n  }\n\n  queueAction({name, commandFn, namespace = 'element()', args = [], rejectPromise = true} = {}) {\n    const opts = {\n      args,\n      context: null,\n      deferred: createPromise(),\n      commandFn,\n      namespace,\n      rejectPromise,\n      commandName: name\n    };\n\n    return this.nightwatchInstance.queue.add(opts);\n  }\n\n  then(onFulfilled, onRejected) {\n    return this.webElements.then(onFulfilled, onRejected);\n  }\n}\n\nmodule.exports = ScopedElements;\n"
  },
  {
    "path": "lib/api/web-element/waitUntil.js",
    "content": "const {until, Condition} = require('selenium-webdriver');\nconst {AssertionRunner} = require('../../assertion');\nconst {isDefined, format} = require('../../utils');\nconst {ScopedElementLocator} = require('./element-locator');\nconst {NoSuchElementError} = require('../../element/locator');\n\nconst mapToSeleniumFunction = {\n  'selected': until.elementIsSelected,\n  'not.selected': until.elementIsNotSelected,\n  'visible': until.elementIsVisible,\n  'not.visible': until.elementIsNotVisible,\n  'enabled': until.elementIsEnabled,\n  'not.enabled': until.elementIsDisabled,\n  'disabled': until.elementIsDisabled,\n  'present': (webElement, scopedElementLocator) => until.elementLocated(scopedElementLocator.condition),\n  'not.present': (webElement, scopedElementLocator) => new Condition('until elmenet is not present', (driver) => driver.findElements(scopedElementLocator.condition).then(elements => elements.length ? false : true))\n};\n\n/**\n * Waits a given time in milliseconds (default 5000ms) for an element to be in the action state provided before performing any other commands or assertions.\n * If the element fails to be in the action state withing the given time, the test fails. You can change this by setting `abortOnFailure` to `false`.\n *\n * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.conf.js` or in your external globals file.\n * Similarly, the default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds).\n *\n * @example\n *  describe('demo Test', function() {\n *   it ('wait for container', async function(browser){\n *     // with default implicit timeout of 5000ms (can be overwritten in settings under 'globals.waitForConditionTimeout')\n *     await browser.element.find('#index-container').waitUntil('visible');\n *\n *     // with explicit timeout (in milliseconds)\n *     await browser.element.find('#index-container').waitUntil('visible', {timeout: 1000});\n *\n *     // continue if failed\n *     await browser.element.find('#index-container').waitUntil('visible', {timeout: 1000, abortOnFailure: false});\n *\n *     // with negative assertion\n *     await browser.element.find('#index-container').waitUntil('not.visible');\n *\n *     // with xpath as the locate strategy\n *     await browser.element.find(by.xpath('//*[@id=\"index-container\"]')).waitUntil('visible', {message: 'The index container is found.'});\n *\n *     // with custom message\n *     await browser.element.find('#index-container').waitUntil('visible', {message: 'The index container is found.'});\n *   });\n *\n *\n *   it('page object demo Test', async function (browser) {\n *     const nightwatchPage = browser.page.nightwatch();\n *\n *     nightwatchPage\n *       .navigate()\n *       .assert.titleContains('Nightwatch.js');\n *\n *     await nightwatchPage.element.find('@featuresList').waitUntil('visible');\n *   });\n * });\n *\n * @method waitUntil\n * @syntax .waitUntil(action, {timeout, retryInterval, message, abortOnFailure});\n * @param {string} action The action state. Should be one of the following: selected, not.selected, visible, not.visible, enabled, disabled, present, not.present\n * @param {number} [timeout] The total number of milliseconds to wait before failing. Can also be set using 'globals.waitForConditionTimeout' under settings.\n * @param {number} [retryInterval] The number of milliseconds to wait between retries. You can use this only if you also specify the time parameter. Can also be set using 'globals.waitForConditionPollInterval' under settings.\n * @param {string} [message] Optional message to be shown in the output. The message supports two placeholders: %s for current selector and %d for the time (e.g. Element %s was not in the page for %d ms).\n * @param {boolean} [abortOnFailure=abortOnAssertionFailure] By the default if the element is not found the test will fail. Set this to false if you wish for the test to continue even if the assertion fails. To set this globally you can define a property `abortOnAssertionFailure` in your globals.\n */\n\nclass WaitUntil {\n  constructor(scopedElement, {action, timeout, retryInterval, message, nightwatchInstance, selector, abortOnFailure}) {\n    this.scopedElement = scopedElement;\n    this.conditionFn = mapToSeleniumFunction[action];\n    this.nightwatchInstance = nightwatchInstance;\n    this.action = action;\n    this.message = message;\n    this.selector = selector;\n    this.timeout = timeout || this.nightwatchInstance.settings.globals.waitForConditionTimeout;\n    this.retryInterval = retryInterval || this.nightwatchInstance.settings.globals.waitForConditionPollInterval;\n    this.abortOnFailure = isDefined(abortOnFailure) ? abortOnFailure : this.nightwatchInstance.settings.globals.abortOnAssertionFailure;\n    this.scopedElementLocator = ScopedElementLocator.create(selector, nightwatchInstance);\n  }\n\n  createNode() {\n    const createAction = (actions, webElementPromise) =>  async function() {\n\n      let result;\n      try {\n\n        if (!this.conditionFn) {\n          throw new Error(`Invalid action ${this.action} for element.waitUntil command. Possible actions: ${Object.keys(mapToSeleniumFunction).toString()}`);\n        }\n\n        const webElement = await webElementPromise;\n\n        if (!webElement && !['present', 'not.present'].includes(this.action)) {\n          throw new NoSuchElementError({element: this.scopedElementLocator, abortOnFailure: this.abortOnFailure});\n        }\n\n        const elapsedTime = new Date().getTime() - node.startTime;\n        const commandResult = await this.scopedElement.driver.wait(this.conditionFn(webElementPromise, this.scopedElementLocator), this.timeout, this.message, this.retryInterval, ()=>{});\n        result = await this.pass(commandResult, elapsedTime).catch(err => err);\n\n        return result;\n      } catch (err) {\n        const elapsedTime = new Date().getTime() - node.startTime;\n        const actual = err instanceof NoSuchElementError ? 'not present' : null;\n        result = await this.fail(err, actual, elapsedTime).catch(err => err);\n\n        return result;\n      } finally {\n        node.deferred.resolve(result);\n      }\n    }.bind(this);\n\n    const node = this.scopedElement.queueAction({name: 'waitUntil', createAction});\n\n    return node;\n  }\n\n\n  async wait() {\n    const assertApi = this.nightwatchInstance.api.assert;\n\n    try {\n      const node =  this.createNode();\n\n      return this.scopedElement.waitFor(node.deferred.promise);\n    } catch (err) {\n      assertApi.ok(false, err.message);\n    }\n  }\n\n  formatMsg(message, timeMs) {\n    const defaultMsg = this.message || message;\n\n    return format(defaultMsg, this.selector, timeMs);\n  }\n\n  assert({result, passed, err, message, elapsedTime}) {\n    const {reporter} = this.scopedElement;\n\n    const runner = new AssertionRunner({abortOnFailure: this.abortOnFailure, passed, err, message, reporter, elapsedTime});\n\n    return runner.run(result);\n  }\n\n  pass(result, elapsedTime) {\n    const sliceAction = this.action.split('.');\n    const expected = sliceAction[0] === 'not' ? `not ${sliceAction[1]}` : this.action;\n    const message = this.formatMsg(`Element <%s> was ${expected} in %d milliseconds`, elapsedTime);\n\n    return this.assert({\n      result,\n      passed: true,\n      err: {\n        expected\n      },\n      elapsedTime,\n      message\n    });\n  }\n\n  fail(result, actual, elapsedTime) {\n    const sliceAction = this.action.split('.');\n\n    actual = actual ? actual : sliceAction[0] === 'not' ? sliceAction[1] : `not ${this.action}`;\n    const expected = sliceAction[0] === 'not' ? `not ${sliceAction[1]}` : this.action;\n    const message = this.formatMsg(`Timed out while waiting for element <%s> to be ${expected} for %d milliseconds`, this.timeout);\n\n    return this.assert({\n      result,\n      passed: false,\n      message,\n      err: {\n        actual,\n        expected\n      },\n      elapsedTime\n    });\n  }\n}\n\nmodule.exports = WaitUntil;\n"
  },
  {
    "path": "lib/assertion/assertion-error.js",
    "content": "const AssertionError = require('assertion-error');\n\nclass NightwatchAssertError extends AssertionError {\n  constructor(message) {\n    super(message);\n\n    this.name = 'NightwatchAssertError';\n  }\n}\n\nmodule.exports = NightwatchAssertError;\n"
  },
  {
    "path": "lib/assertion/assertion-runner.js",
    "content": "const NightwatchAssertion = require('./assertion.js');\nconst Utils = require('../utils/');\nconst {Logger} = Utils;\n\nmodule.exports = class AssertionRunner {\n  /**\n   * This is deprecated. No longer possible to check the httpStatusCode of the command.\n   *\n   * @deprecated\n   * @param result\n   * @returns {boolean|boolean|*}\n   */\n  static isServerError(result = {}) {\n    if (!result) {\n      return false;\n    }\n\n    const {status, error, httpStatusCode} = result;\n\n    return (status === -1 && error && httpStatusCode && httpStatusCode.toString().startsWith('5'));\n  }\n\n  /**\n   * @param opts = {passed, err, calleeFn, message, stackTrace, abortOnFailure, reporter, addExpected = true}\n   */\n  constructor(opts = {}) {\n    this.opts = opts;\n    this.create();\n  }\n\n  create() {\n    const {passed, err, calleeFn = null, message = '', abortOnFailure = true, stackTrace = '', showTrace, link, help} = this.opts;\n\n    this.assertion = new NightwatchAssertion(message);\n    if (Utils.isDefined(showTrace)) {\n      this.assertion.showTrace = showTrace;\n    }\n\n    if (Utils.isDefined(help)) {\n      this.assertion.help = help;\n    }\n\n    if (Utils.isDefined(link)) {\n      this.assertion.link = link;\n    }\n\n    this.assertion.failure = !passed && !err.actual;\n    this.assertion.expected = err.expected;\n    this.assertion.actual = err.actual;\n    this.assertion.passed = passed;\n    this.assertion.stackTrace = stackTrace || calleeFn && calleeFn.stackTrace;\n    this.assertion.calleeFn = calleeFn;\n    this.assertion.abortOnFailure = abortOnFailure;\n    this.assertion.stackTraceTitle = true;\n  }\n\n  async run(commandResult = {value: null}) {\n    const {reporter} = this.opts;\n    let assertResult;\n    let isError = false;\n\n    if (commandResult && AssertionRunner.isServerError(commandResult)) {\n      const errorMessage = commandResult.error || 'Unknown server error';\n      this.assertion.passed = false;\n      this.assertion.actual = `Server Error: ${errorMessage}`;\n    }\n\n    try {\n      await this.assertion.assert();\n      reporter.registerPassed(this.assertion.message);\n    } catch (e) {\n      const {error} = this.assertion;\n      error.abortOnFailure = this.opts.abortOnFailure;\n      isError = true;\n      const {addExpected = true, elapsedTime} = this.opts;\n      this.assertion.buildStackTrace().setMessage(addExpected, elapsedTime).setFailedMessage();\n\n      Logger.error(error);\n      reporter.registerFailed(error);\n\n      assertResult = error;\n    }\n\n    reporter.logAssertResult(this.assertion.getAssertResult());\n\n    if (isError) {\n      return Promise.reject(assertResult);\n    }\n\n    const promiseResult = Object.assign({}, commandResult);\n    promiseResult.returned = 1;\n\n    return Promise.resolve(promiseResult);\n  }\n};\n"
  },
  {
    "path": "lib/assertion/assertion.js",
    "content": "const NightwatchAssertError = require('./assertion-error.js');\nconst Utils = require('../utils');\nconst {Logger, stringifyObject} = Utils;\n\nclass NightwatchAssertion {\n  static getExpectedMessage({expected, actual}) {\n\n    const expectedMsg = Logger.colors.green(stringifyObject(expected));\n    const receivedMsg = Logger.colors.red(stringifyObject(actual));\n\n    return ` - expected ${expectedMsg} but got: ${receivedMsg}`;\n  }\n\n  constructor(message) {\n    this.__err = new NightwatchAssertError(message);\n    this.__stackTraceTitle = message;\n    this.__abortOnFailure = true;\n\n    this.failureMessage = '';\n\n    this.message = message;\n    this.calleeFn = undefined;\n    this.actual = undefined;\n    this.expected = undefined;\n    this.stackTrace = undefined;\n    this.passed = undefined;\n    this.failure = false;\n  }\n\n  get error() {\n    return this.__err;\n  }\n\n  set stackTraceTitle(val) {\n    this.__stackTraceTitle = val ? null : `AssertionError: ${this.message}`;\n  }\n\n  set showTrace(value) {\n    this.__err.showTrace = value;\n  }\n\n  set link(value) {\n    this.__err.link = value;\n  }\n\n  set help(value) {\n    this.__err.help = value;\n  }\n\n  get stackTraceTitle() {\n    return this.__stackTraceTitle;\n  }\n\n  set abortOnFailure(value) {\n    this.__abortOnFailure = value;\n    this.__err.abortOnFailure = value;\n  }\n\n  get abortOnFailure() {\n    return this.__abortOnFailure;\n  }\n\n  buildStackTrace() {\n    const stackTrace = this.stackTrace || this.captureStackTrace(this.calleeFn);\n    const sections = stackTrace.split('\\n');\n\n    sections.shift();\n\n    if (this.stackTraceTitle) {\n      sections.unshift(this.stackTraceTitle);\n    }\n\n    this.error.stack = Utils.stackTraceFilter(sections);\n\n    return this;\n  }\n\n  setFailedMessage() {\n    if (this.expected !== undefined && this.actual !== undefined) {\n      this.failureMessage = `Expected \"${this.expected}\" but got: \"${this.actual}\"`;\n    }\n\n    return this;\n  }\n\n  setMessage(needsExpected = true, elapsedTime) {\n    const {actual, expected} = this;\n\n    if (expected !== undefined && actual !== undefined && needsExpected) {\n      this.message += NightwatchAssertion.getExpectedMessage({\n        actual, expected\n      }) + ' ' + Logger.colors.stack_trace(`(${elapsedTime}ms)`);\n    }\n\n    this.error.message = this.message;\n\n    return this;\n  }\n\n  getAssertResult() {\n    const result = {\n      name: this.error.name,\n      message: this.message,\n      stackTrace: this.passed ? '' : this.error.stack,\n      fullMsg: this.message,\n      failure: this.failureMessage !== '' ? this.failureMessage : this.failure\n    };\n\n    if (Utils.isDefined(this.error.link)) {\n      result.link = this.error.link;\n    }\n\n    if (Utils.isDefined(this.error.help)) {\n      result.help = this.error.help;\n    }\n\n    return result;\n  }\n\n  captureStackTrace(calleeFn) {\n    Error.captureStackTrace(this.error, calleeFn);\n\n    return this.error.stack;\n  }\n\n  assert() {\n    return this.passed ?\n      Promise.resolve() :\n      Promise.reject();\n  }\n}\n\nmodule.exports = NightwatchAssertion;\n"
  },
  {
    "path": "lib/assertion/index.js",
    "content": "const assertion = require('./assertion.js');\nconst AssertionRunner = require('./assertion-runner.js');\nconst AssertionError = require('./assertion-error.js');\n\nmodule.exports = assertion;\nmodule.exports.AssertionRunner = AssertionRunner;\nmodule.exports.AssertionError = AssertionError;\n"
  },
  {
    "path": "lib/core/asynctree.js",
    "content": "const EventEmitter = require('events');\nconst Utils = require('../utils');\nconst TreeNode = require('./treenode.js');\nconst {Logger} = Utils;\nconst Debuggability = require('../utils/debuggability.js');\n\nclass AsyncTree extends EventEmitter{\n  get started() {\n    return this.rootNode.started;\n  }\n\n  get rootNode() {\n    return this.__rootNode__;\n  }\n\n  get inProgress() {\n    return this.currentNode.started && !this.currentNode.done;\n  }\n\n  constructor({compatMode, foreignRunner, cucumberRunner, mochaRunner}) {\n    super();\n    this.compatMode = compatMode;\n    this.foreignRunner = foreignRunner;\n    this.cucumberRunner = cucumberRunner;\n    this.mochaRunner = mochaRunner;\n    this.createRootNode();\n    this.returnError = null;\n  }\n\n  addNode(node) {\n    this.currentNode.childNodes.push(node);\n  }\n\n  createRootNode() {\n    this.__rootNode__ = new TreeNode({\n      name: '__root__',\n      parent: null\n    });\n\n    this.currentNode = this.rootNode;\n  }\n\n  async traverse(err) {\n    this.rootNode.started = true;\n    const childNode = AsyncTree.getNextChildNode(this.currentNode);\n\n    if (childNode) {\n      const result = await this.runChildNode(childNode);\n\n      if (result instanceof Error && result.namespace === 'verify') {\n        return null;\n      }\n\n      return result;\n    }\n\n    if (this.currentNode.childNodes.length > 0 && this.currentNode.needsPromise) {\n      this.currentNode.deferred.resolve();\n    } else if (this.currentNode.isRootNode) {\n      const result = await this.done(err);\n\n      return result;\n    }\n\n    return await this.walkUp(err);\n  }\n\n  async walkUp(err) {\n    if (this.currentNode.childNodes.length > 0 && !this.currentNode.done) {\n      // if the current node has childNodes that have not finished yet\n      return this.currentNode.deferred.promise;\n    }\n\n    if (!this.currentNode.done) {\n      // if the current node hasn't finished yet\n      return err;\n    }\n\n    this.currentNode = this.currentNode.parent;\n\n    return await this.traverse(err);\n  }\n\n  otherChildNodesInProgress(node) {\n    const parentNode = node.parent;\n\n    if (!parentNode || parentNode.isRootNode) {\n      return false;\n    }\n\n    return parentNode.childNodes.filter(item => item !== node && !item.done).length > 0;\n  }\n\n  shouldAvoidParentNodeResolution(node) {\n    const parentNode = node.parent;\n\n    if (!parentNode || parentNode.isRootNode) {\n      return true;\n    }\n\n    const result = parentNode.options?.avoidPrematureParentNodeResolution;\n\n    return Boolean(result);\n  }\n\n  shouldRejectNodePromise(err, abortOnFailure, node = this.currentNode) {\n    const rejectNodeOnAbortFailure = node.options?.rejectNodeOnAbortFailure;\n\n    if ((err.isExpect || node.namespace === 'assert' || (abortOnFailure && rejectNodeOnAbortFailure)) && node.isES6Async) {\n      return true;\n    }\n\n    if (this.cucumberRunner) {\n      return err.waitFor;\n    }\n\n    return node.rejectPromise || err.rejectPromise;\n  }\n\n  shouldRejectParentNodePromise(err, node = this.currentNode) {\n    const {parent} = node;\n    if (!parent || this.mochaRunner) {\n      return false;\n    }\n\n    return err.name !== 'NightwatchAssertError' && !err.isExpect && !parent.isRootNode && parent.isES6Async;\n  }\n\n  async runChildNode(node) {\n    this.currentNode = node;\n    this.currentNode.started = true;\n    Logger.log(`\\n ${Logger.colors.green('→')} Running command: ${Logger.colors.green(node.fullName)}${AsyncTree.printArguments(node)}`);\n\n    this.emit('asynctree:command:start', {node});\n\n    const result = await node.run();\n\n    let abortOnFailure = false;\n    let err;\n\n    if (result instanceof Error) {\n      err = node.handleError(result);\n      err.namespace = node.namespace;\n\n      abortOnFailure = err.abortOnFailure || Utils.isUndefined(err.abortOnFailure);\n      if (this.foreignRunner) {\n        err.stack = err.stack.split('\\n').slice(1).join('\\n');\n      }\n\n      if (this.shouldRejectNodePromise(err, abortOnFailure, node)) {\n        node.reject(err);\n      } else {\n        node.resolve(err);\n      }\n\n      if (this.shouldRejectParentNodePromise(err, node)) {\n        node.parent.reject(err);\n      }\n    } else {\n      node.resolveValue = result;\n      this.resolveNode(node, result);\n    }\n\n    Logger.log(`${Logger.colors.green('→')} Completed command: ${Logger.colors.green(node.fullName)}` +\n      `${AsyncTree.printArguments(node)} (${node.elapsedTime}ms)`);\n\n    this.emit('asynctree:command:finished', {node, result});\n\n    if (abortOnFailure) {\n      this.empty();\n      this.createRootNode();\n      this.returnError = err; // this is to make assertions return the proper errors\n      this.emit('asynctree:finished', this);\n\n      return err;\n    }\n\n    if (Debuggability.stepOverAndPause && node.parent.isRootNode && node.fullName !== 'pause') {\n      this.currentNode.context.api.pause();\n      // Whether to stop after performing next step will be decided\n      // in the next \"paused\" prompt.\n      Debuggability.stepOverAndPause = false;\n    }\n\n    return await this.traverse(err);\n  }\n\n  resolveNode(node, result, times = 0) {\n    if (times === 5) {\n      return;\n    }\n\n    if (!node.isRootNode) {\n      node.resolve(result);\n    }\n\n    setTimeout(() => {\n      const stillInProgress = this.otherChildNodesInProgress(node);\n      const avoidPrematureParentNodeResolution = this.shouldAvoidParentNodeResolution(node);\n\n      if (node.context && node.context instanceof EventEmitter) {\n        node.context.emit('complete');\n      }\n\n      const isAssertion = node.parent && (node.parent.namespace === 'assert' || node.parent.namespace === 'verify');\n      if (node.parent && !node.parent.isRootNode && !isAssertion && !stillInProgress && !avoidPrematureParentNodeResolution) {\n        node.done = true;\n        this.resolveNode(node.parent, result, ++times);\n      }\n    }, 10);\n  }\n\n  async done(err = null) {\n    // `this.currentTestCaseResult` represents the return value of the\n    // currently executing `it` test case or hook.\n    // We do not want to clear the tree if the test case is still running.\n    // In case of an error, the tree will be cleared in the `runChildNode`\n    // method itself.\n    if (this.currentTestCaseResult instanceof Promise && !this.currentTestCaseResult.settled) {\n      return err;\n    }\n\n    this.emit('asynctree:finished', this);\n    this.empty();\n    this.createRootNode();\n\n    // Test case is complete, reset Debuggability properties.\n    Debuggability.reset();\n\n    return err;\n  }\n\n  empty() {\n    this.rootNode.childNodes = [];\n\n    return this;\n  }\n\n  reset() {\n    this.rootNode.started = false;\n    this.rootNode.done = false;\n    this.currentNode = this.rootNode;\n\n    return this;\n  }\n\n  ///////////////////////////////////////////////////////////////////////////\n  // STATIC\n  ///////////////////////////////////////////////////////////////////////////\n  static getNextChildNode(node) {\n    let childNode;\n    for (let i = 0; i < node.childNodes.length; i++) {\n      if (!node.childNodes[i].started) {\n        return node.childNodes[i];\n      }\n\n      if (node.childNodes[i].childNodes.length > 0) {\n        childNode = node.childNodes[i];\n      }\n    }\n\n    return false;\n  }\n\n  static get argFilters() {\n    return {\n      setValue(...args) {\n        if (args.length === 4) {\n          args[2] = '<redacted>';\n        } else if (args.length === 3) {\n          args[1] = '<redacted>';\n        }\n\n        return args;\n      }\n    };\n  }\n\n  static printArguments(node) {\n    let args = node.args ? node.args.slice(0) : [];\n    if (AsyncTree.argFilters[node.name]) {\n      args = AsyncTree.argFilters[node.name](...args);\n    }\n\n    const argsContent = args.map(function(arg) {\n      if (arg === null || arg === undefined) {\n        return arg;\n      }\n\n      switch (typeof arg) {\n        case 'function':\n          return '[Function]';\n        case 'string':\n          return node.redact ? '**********' : `'${arg}'`;\n        case 'object': {\n          if (node.printArgs) {\n            return node.printArgs();\n          }\n\n          const keys = Object.keys(arg);\n\n          return `{${keys.length < 10 ? keys.join(', ') : (keys.slice(0, 10).join(', ') + '...')}}`;\n        }\n        default:\n          return arg.toString();\n      }\n    }).join(', ');\n\n    return Logger.colors.cyan(` (${argsContent})`);\n  }\n}\n\nmodule.exports = AsyncTree;\n"
  },
  {
    "path": "lib/core/client.js",
    "content": "const EventEmitter = require('events');\nconst {Key, Capabilities, Browser} = require('selenium-webdriver');\n\nconst lodashMerge = require('lodash/merge');\nconst HttpRequest = require('../http/request.js');\nconst Utils = require('../utils');\nconst Settings = require('../settings/settings.js');\nconst CommandQueue = require('./queue.js');\nconst Transport = require('../transport');\nconst Element = require('../element');\nconst ApiLoader = require('../api');\nconst ElementGlobal = require('../api/_loaders/element-global.js');\nconst Factory = require('../transport/factory.js');\nconst {isAndroid, isIos} = require('../utils/mobile');\nconst namespacedApi = require('../core/namespaced-api.js');\nconst cdp = require('../transport/selenium-webdriver/cdp.js');\n\nconst {LocateStrategy, Locator} = Element;\nconst {Logger, isUndefined, isDefined, isObject, isFunction, isSafari, isChrome} = Utils;\n\nclass NightwatchAPI {\n  get WEBDRIVER_ELEMENT_ID() {\n    return Transport.WEB_ELEMENT_ID;\n  }\n\n  get browserName() {\n    if (this.capabilities && this.capabilities.browserName) {\n      return this.capabilities.browserName;\n    }\n\n    if (this.desiredCapabilities instanceof Capabilities) {\n      return this.desiredCapabilities.getBrowserName();\n    }\n\n    return this.desiredCapabilities.browserName;\n  }\n\n  get platformName() {\n    if (this.capabilities && this.capabilities.platformName) {\n      return this.capabilities.platformName;\n    }\n\n    if (this.desiredCapabilities instanceof Capabilities) {\n      return this.desiredCapabilities.getPlatform();\n    }\n\n    return this.desiredCapabilities.platformName;\n  }\n\n  toString() {\n    return 'Nightwatch API';\n  }\n\n  constructor(sessionId, settings) {\n    // session returned capabilities\n    this.capabilities = {};\n    this.currentTest = null;\n\n    // requested capabilities\n    this.desiredCapabilities = settings.capabilities instanceof Capabilities ? settings.capabilities : settings.desiredCapabilities;\n    this.sessionId = sessionId;\n    this.options = settings;\n    this.globals = settings.globals;\n  }\n\n  __isBrowserName(browser, alternateName) {\n    const lowerCaseBrowserName = this.browserName && this.browserName.toLowerCase();\n    const browserNames = [this.browserName, lowerCaseBrowserName];\n\n    if (alternateName) {\n      alternateName = Array.isArray(alternateName)\n        ? alternateName\n        : [alternateName];\n\n      return [browser, ...alternateName].some(name =>\n        browserNames.includes(name)\n      );\n    }\n\n    return browserNames.includes(browser);\n  }\n\n  __isPlatformName(platform) {\n    if (typeof this.platformName === 'undefined') {\n      return false;\n    }\n\n    return this.platformName.toLowerCase() === platform.toLowerCase();\n  }\n\n  isIOS() {\n    return isIos(this.desiredCapabilities);\n  }\n\n  isAndroid() {\n    return isAndroid(this.desiredCapabilities);\n  }\n\n  isMobile() {\n    return this.isIOS() || this.isAndroid();\n  }\n\n  isSafari() {\n    return isSafari(this.desiredCapabilities);\n  }\n\n  isChrome() {\n    return isChrome(this.desiredCapabilities);\n  }\n\n  isFirefox() {\n    return this.__isBrowserName(Browser.FIREFOX);\n  }\n\n  isEdge() {\n    return this.__isBrowserName(Browser.EDGE, ['edge', 'msedge']);\n  }\n\n  isInternetExplorer() {\n    return this.__isBrowserName(Browser.INTERNET_EXPLORER);\n  }\n\n  isOpera() {\n    return this.capabilities.browserName === Browser.OPERA;\n  }\n\n  isAppiumClient() {\n    if (this.options.selenium && this.options.selenium.use_appium) {\n      return true;\n    }\n\n    // Handle BrowserStack case\n    // (BrowserStack always returns platformName in capabilities)\n    const isMobile = this.__isPlatformName('android') || this.__isPlatformName('ios');\n    if (Factory.usingBrowserstack(this.options) && isMobile) {\n      return true;\n    }\n\n    return false;\n  }\n}\n\nclass NightwatchClient extends EventEmitter {\n\n  static create(settings, argv) {\n    const client = new NightwatchClient(settings, argv);\n\n    if (!client.settings.disable_global_apis) {\n      Object.defineProperty(global, 'browser', {\n        configurable: true,\n        get: function() {\n          if (client) {\n            return client.api;\n          }\n\n          return null;\n        }\n      });\n    }\n\n    // clear namespaced api\n    for (const namespace of Object.getOwnPropertyNames(namespacedApi)) {\n      if (namespacedApi[namespace].__isProxy) {\n        namespacedApi[namespace] = {};\n      } else if (Utils.isObject(namespacedApi[namespace])) {\n        for (const key of Object.getOwnPropertyNames(namespacedApi[namespace])) {\n          delete namespacedApi[namespace][key];\n        }\n      }\n    }\n\n    return client;\n  }\n\n  constructor(userSettings = {}, argv = {}) {\n    super();\n\n    this.setMaxListeners(0);\n\n    this.settings = Settings.fromClient(userSettings, argv);\n    Logger.setOptions(this.settings);\n\n    this.isES6AsyncTestcase = false;\n    this.isES6AsyncCommand = false;\n\n    // backwards compatibility\n    this.options = this.settings;\n    this.__sessionId = null;\n    this.__argv = argv;\n    this.__locateStrategy = null;\n    this.__transport = null;\n    this.createCommandQueue();\n\n    this.__elementLocator = new Locator(this);\n    this.__reporter = {\n      logFailedAssertion(err) {\n      },\n      registerTestError(err) {\n        Logger.error(err);\n      }\n    };\n\n    this.__overridableCommands = new Set();\n\n    this.__api = new NightwatchAPI(this.sessionId, this.settings);\n\n    this.__api.createElement = (locator, options = {}) => {\n      return ElementGlobal.element({locator, client: this, options});\n    };\n\n    this\n      .setLaunchUrl()\n      .setScreenshotOptions()\n      .setConfigLocateStrategy()\n      .setLocateStrategy()\n      .setSessionOptions()\n      .createApis();\n  }\n\n  get overridableCommands() {\n    return this.__overridableCommands;\n  }\n\n  get api() {\n    return this.__api;\n  }\n\n  get argv() {\n    return this.__argv;\n  }\n\n  get queue() {\n    return this.__commandQueue;\n  }\n\n  get locateStrategy() {\n    return this.__locateStrategy;\n  }\n\n  get configLocateStrategy() {\n    return this.__configLocateStrategy;\n  }\n\n  get sessionId() {\n    return this.getSessionId();\n  }\n\n  get usingCucumber() {\n    if (!this.settings.test_runner) {\n      return false;\n    }\n\n    return this.settings.test_runner.type === 'cucumber';\n  }\n\n  getSessionId() {\n    return this.__sessionId;\n  }\n\n  set sessionId(val) {\n    this.__sessionId = val;\n  }\n\n  get transport() {\n    return this.__transport;\n  }\n\n  get transportActions() {\n    const actions = this.transport.Actions;\n    const api = this.api;\n\n    return new Proxy(actions, {\n      get(target, name) {\n        return function (...args) {\n          let callback;\n          let method;\n          let sessionId = api.sessionId;\n          const lastArg = args[args.length - 1];\n          const isLastArgFunction = Utils.isFunction(lastArg);\n\n          if (isLastArgFunction) {\n            callback = args.pop();\n          } else if (args.length === 0 || !isLastArgFunction) {\n            callback = function(result) {return result};\n          }\n\n          const definition = {\n            args\n          };\n\n          if (Array.isArray(args[0]) && Utils.isString(lastArg)) {\n            sessionId = lastArg;\n            definition.args = args[0];\n          }\n\n          if (Utils.isString(name)) {\n            if (name in target.session) { // actions that require the current session\n              method = target.session[name];\n              definition.sessionId = api.sessionId || sessionId;\n            } else {\n              method = target[name];\n            }\n\n            //return method(definition).then((result) => Utils.makePromise(callback, api, [result]));\n\n            return method(definition)\n              .then(async (result) => {\n                if (result && result.error && ((result.error instanceof TypeError) || (result.error instanceof SyntaxError))) {\n                  throw result.error;\n                }\n                const newResult = await Utils.makePromise(callback, api, [result]);\n\n                if (Utils.isUndefined(newResult)) {\n                  return result;\n                }\n\n                return newResult;\n              })\n              .catch(err => {\n                Logger.error(err);\n                callback(err);\n              });\n          }\n\n          if (typeof name == 'symbol') {\n            // this is in case of console.log(this.transportActions)\n            const util = require('util');\n            const result = Object.keys(target).reduce((prev, key) => {\n              if (key === 'session') {\n                return prev;\n              }\n\n              prev[key] = target[key];\n\n              return prev;\n            }, {});\n\n            Object.assign(result, target.session);\n\n            const sorted = Object.keys(result).sort().reduce((prev, key) => {\n              prev[key] = result[key];\n\n              return prev;\n            }, {});\n\n            return util.inspect(sorted);\n          }\n\n          return Promise.resolve();\n        };\n      }\n    });\n  }\n\n  get elementLocator() {\n    return this.__elementLocator;\n  }\n\n  get httpOpts() {\n    return this.__httpOpts;\n  }\n\n  get startSessionEnabled() {\n    return this.settings.start_session;\n  }\n\n  get unitTestingMode() {\n    return this.settings.unit_tests_mode;\n  }\n\n  screenshotsEnabled() {\n    return isObject(this.settings.screenshots) ? (this.settings.screenshots && this.options.screenshots.enabled === true) : false;\n  }\n\n  get reporter() {\n    return this.__reporter || {};\n  }\n\n  get client() {\n    const {settings, api, locateStrategy, reporter, sessionId, elementLocator} = this;\n\n    return {\n      options: settings,\n      settings,\n      api,\n      locateStrategy,\n      reporter,\n      sessionId,\n      elementLocator\n    };\n  }\n\n  createApis() {\n    this.setApiProperty('page', {});\n    this.setApiProperty('assert', {});\n    this.setApiProperty('verify', {});\n\n    if (!this.unitTestingMode) {\n      this.setApiProperty('ensure', {});\n      this.setApiProperty('chrome', {});\n      this.setApiProperty('firefox', {});\n    }\n\n    Object.defineProperty(this.__api, 'driver', {\n      configurable: true,\n      enumerable: true,\n      get: function() {\n        return this.transport && this.transport.driver;\n      }.bind(this)\n    });\n\n    this.setApiMethod('actions', (opts) => {\n      return this.transport.driver.actions(opts);\n    });\n  }\n\n  //////////////////////////////////////////////////////////////////////////////////////////\n  // Setters\n  //////////////////////////////////////////////////////////////////////////////////////////\n  setApiProperty(key, value) {\n    if (Utils.isFunction(value)) {\n      Object.defineProperty(this.__api, key, {\n        get: value\n      });\n    } else {\n      this.__api[key] = value;\n    }\n\n\n    return this;\n  }\n\n  setApiOption(key, value) {\n    this.__api.options[key] = value;\n\n    return this;\n  }\n\n  /**\n   *\n   * @param key\n   * @param args\n   * @return {NightwatchClient}\n   */\n  setApiMethod(key, ...args) {\n    let fn;\n    let context = this.__api;\n\n    if (args.length === 1) {\n      fn = args[0];\n    } else if (args.length === 2) {\n      const namespace = typeof args[0] == 'string' ? context[args[0]] : args[0];\n      if (namespace) {\n        context = namespace;\n      }\n\n      fn = args[1];\n    }\n\n    if (!fn) {\n      throw new Error('Method must be a declared.');\n    }\n\n    context[key] = fn;\n\n    return this;\n  }\n\n  setNamespacedApiMethod(key, ...args) {\n    if (args.length < 1 || args.length > 2) {\n      throw new Error('Invalid number of arguments passed.');\n    }\n\n    const fn = args.pop();\n    if (!fn) {\n      throw new Error('Method must be a declared.');\n    }\n\n    const context = (typeof args[0] === 'string' ? namespacedApi[args[0]] : args[0]) || namespacedApi;\n\n    context[key] = fn;\n\n    return this;\n  }\n\n  /**\n   *\n   * @param {string} key\n   * @param {string|object} namespace\n   * @return {boolean}\n   */\n  isApiMethodDefined(key, namespace) {\n    let api = this.__api;\n    if (namespace) {\n      api = typeof namespace == 'string' ? api[namespace] : namespace;\n\n      if (api === undefined) {\n        return false;\n      }\n    }\n\n    return api[key] !== undefined;\n  }\n\n  setReporter(reporter) {\n    this.__reporter = reporter;\n\n    return this;\n  }\n\n  //////////////////////////////////////////////////////////////////////////////////////////\n  // Options\n  //////////////////////////////////////////////////////////////////////////////////////////\n  /**\n   * @deprecated\n   */\n  endSessionOnFail(val) {\n    if (arguments.length === 0) {\n      return this.settings.end_session_on_fail;\n    }\n\n    this.settings.end_session_on_fail = val;\n  }\n\n  setLaunchUrl() {\n    let value = this.settings.baseUrl || this.settings.launchUrl || this.settings.launch_url || null;\n\n    // For e2e and component testing on android emulator\n    if (value && !this.settings.desiredCapabilities.real_mobile && this.settings.desiredCapabilities.avd) {\n      value = value.replace('localhost', '10.0.2.2').replace('127.0.0.1', '10.0.2.2');\n    }\n\n    this\n      .setApiProperty('baseUrl', value)\n      .setApiProperty('launchUrl', value)\n      .setApiProperty('launch_url', value);\n\n    return this;\n  }\n\n  setScreenshotOptions() {\n    const {screenshots} = this.settings;\n\n    if (this.screenshotsEnabled()) {\n      this.setApiProperty('screenshotsPath', screenshots.path)\n        .setApiOption('screenshotsPath', screenshots.path);\n    }\n\n    return this;\n  }\n\n  setConfigLocateStrategy() {\n    this.__configLocateStrategy = this.settings.use_xpath ? LocateStrategy.XPATH : LocateStrategy.CSS_SELECTOR;\n\n    return this;\n  }\n\n  setLocateStrategy(strategy = null) {\n    if (strategy && LocateStrategy.isValid(strategy)) {\n      this.__locateStrategy = strategy;\n\n      return this;\n    }\n\n    this.__locateStrategy = this.configLocateStrategy;\n\n    return this;\n  }\n\n  get initialCapabilities() {\n    if (isObject(this.settings.capabilities) && Object.keys(this.settings.capabilities).length > 0) {\n      return this.settings.capabilities;\n    }\n\n    return this.settings.desiredCapabilities;\n  }\n\n  setInitialCapabilities(value) {\n    if (isObject(this.settings.capabilities) && Object.keys(this.settings.capabilities).length > 0) {\n      this.settings.capabilities = value;\n    } else {\n      this.settings.desiredCapabilities = value;\n    }\n  }\n\n  setSessionOptions() {\n    this.setApiOption('desiredCapabilities', this.initialCapabilities);\n\n    return this;\n  }\n\n  mergeCapabilities(props = {}) {\n    if (isFunction(props)) {\n      this.setInitialCapabilities(props);\n\n      return;\n    }\n\n    lodashMerge(this.initialCapabilities, props);\n    this.setSessionOptions();\n  }\n\n  setHttpOptions() {\n    this.settings.webdriver = this.settings.webdriver || {};\n\n    if (isUndefined(this.settings.webdriver.port)) {\n      this.settings.webdriver.port = this.transport.defaultPort;\n    }\n\n    if (isUndefined(this.settings.webdriver.default_path_prefix)) {\n      this.settings.webdriver.default_path_prefix = this.transport.defaultPathPrefix;\n    }\n\n    if (this.settings.testWorkersEnabled && this.settings.webdriver.start_process) {\n      // when running in parallel with test workers, the port needs to be randomly assigned\n      this.settings.webdriver.port = undefined;\n    }\n\n    const {\n      port,\n      host,\n      timeout_options = {},\n      ssl = false,\n      keep_alive,\n      proxy,\n      default_path_prefix,\n      username,\n      access_key,\n      internal_server_error_retry_interval\n    } = this.settings.webdriver;\n\n    if (port) {\n      this.httpOpts.setPort(port);\n    }\n\n    if (host) {\n      this.httpOpts.setHost(host);\n    }\n\n    this.httpOpts.useSSL(ssl);\n    this.httpOpts.setKeepAlive(keep_alive);\n\n    if (isDefined(proxy)) {\n      this.httpOpts.setProxy(proxy);\n    }\n\n    if (isDefined(timeout_options.timeout)) {\n      this.httpOpts.setTimeout(timeout_options.timeout);\n    }\n\n    if (isDefined(timeout_options.retry_attempts)) {\n      this.httpOpts.setRetryAttempts(timeout_options.retry_attempts);\n    }\n\n    if (isDefined(internal_server_error_retry_interval)) {\n      this.httpOpts.setInternalServerRetryIntervel(internal_server_error_retry_interval);\n    }\n\n    if (isDefined(default_path_prefix)) {\n      this.httpOpts.setDefaultPathPrefix(default_path_prefix);\n    }\n\n    if (username && isDefined(access_key)) {\n      this\n        .setApiOption('username', username)\n        .setApiOption('accessKey', access_key);\n\n      this.httpOpts.setCredentials({\n        username: username,\n        key: access_key\n      });\n    }\n\n    HttpRequest.globalSettings = this.httpOpts.settings;\n\n    return this;\n  }\n\n  //////////////////////////////////////////////////////////////////////////////////////////\n  // Initialize the APIs\n  //////////////////////////////////////////////////////////////////////////////////////////\n\n  async initialize(loadNightwatchApis = true) {\n    this.loadKeyCodes();\n\n    if (loadNightwatchApis) {\n      return this.loadNightwatchApis();\n    }\n\n    return this;\n  }\n\n  setCurrentTest() {\n    this.setApiProperty('currentTest', () => this.reporter.currentTest);\n\n    return this;\n  }\n\n  loadKeyCodes() {\n    this.setApiProperty('Keys', Key);\n\n    return this;\n  }\n\n  async loadNightwatchApis() {\n    await ApiLoader.init(this);\n\n    const assertApi = Object.assign({}, this.__api.assert);\n    const verifyApi = Object.assign({}, this.__api.verify);\n\n    if (!this.unitTestingMode) {\n      const ensureApi = Object.assign({}, this.__api.ensure);\n      this.__api.ensure = ApiLoader.makeAssertProxy(ensureApi);\n    }\n\n    this.__api.assert = ApiLoader.makeAssertProxy(assertApi);\n    this.__api.verify = ApiLoader.makeAssertProxy(verifyApi);\n\n    // Add proxies for namespaced API\n    namespacedApi.assert = ApiLoader.makeAssertProxy(Object.assign({}, namespacedApi.assert));\n    namespacedApi.verify = ApiLoader.makeAssertProxy(Object.assign({}, namespacedApi.verify));\n\n    return this;\n  }\n\n  createTransport() {\n    const HttpOptions = require('../http/options.js');\n    this.__httpOpts = HttpOptions.global;\n    this.__transport = Transport.create(this);\n    this.setHttpOptions();\n\n    return this;\n  }\n\n  createCommandQueue() {\n    const {type: runner} = this.settings.test_runner;\n\n    this.__commandQueue = new CommandQueue({\n      compatMode: this.settings.backwards_compatibility_mode,\n      foreignRunner: runner !== 'default',\n      mochaRunner: runner === 'mocha',\n      cucumberRunner: runner === 'cucumber'\n    });\n  }\n\n  //////////////////////////////////////////////////////////////////////////////////////////\n  // Session\n  //////////////////////////////////////////////////////////////////////////////////////////\n  /**\n   * @return {Promise}\n   */\n  createSession({argv, moduleKey = '', reuseBrowser = false} = {}) {\n    if (!this.startSessionEnabled) {\n      return Promise.resolve();\n    }\n\n    return this.transport.createSession({argv, moduleKey, reuseBrowser})\n      .then(data => {\n        this.sessionId = data.sessionId;\n        this.setApiProperty('sessionId', data.sessionId);\n        this.setApiProperty('capabilities', data.capabilities);\n\n        Logger.info(`Received session with ID: ${data.sessionId}\\n`);\n\n        // Reset cdp connection every time a new webdriver session is created.\n        cdp.resetConnection();\n\n        this.emit('nightwatch:session.create', data);\n\n        return data;\n      });\n  }\n\n  /**\n   * @deprecated\n   * @return {Promise}\n   */\n  startSession() {\n    return this.createSession();\n  }\n}\n\nmodule.exports = NightwatchClient;\n"
  },
  {
    "path": "lib/core/namespaced-api.js",
    "content": "const namespacedApi = {\n  browser: {},\n  app: {},\n\n  appium: {},\n  alerts: {},\n  cookies: {},\n  document: {},\n  window: {},\n\n  chrome: {},\n  firefox: {},\n\n  assert: {},\n  verify: {},\n  expect: function() {},\n\n  element: function() {}\n};\n\nmodule.exports = namespacedApi;\n"
  },
  {
    "path": "lib/core/queue.js",
    "content": "const EventEmitter = require('events');\nconst AsyncTree = require('./asynctree.js');\nconst Utils = require('../utils');\nconst Node = require('./treenode.js');\n\nclass CommandQueue extends EventEmitter {\n  constructor({compatMode = false, foreignRunner = false, cucumberRunner = false, mochaRunner = false} = {}) {\n    super();\n    this.isDone = false;\n    this.compatMode = compatMode;\n    this.tree = new AsyncTree({compatMode, foreignRunner, cucumberRunner, mochaRunner});\n    this.scheduleTimeoutId = null;\n  }\n\n  get currentNode() {\n    return this.tree.currentNode;\n  }\n\n  get started() {\n    return this.tree.rootNode.started;\n  }\n\n  shouldStartQueue() {\n    const childNodes = this.currentNode.childNodes;\n    const allChildNodesDone = childNodes.every(function(node) {\n      return node.done;\n    });\n\n    return this.currentNode.started && allChildNodesDone;\n  }\n\n  add(command) {\n    const {commandName, commandFn, context = {}, args, stackTrace, namespace, options = {}, deferred, isES6Async, rejectPromise} = command;\n    const {compatMode} = this;\n    const parentContext = this.currentNode.context;\n\n    if (!this.deferred) {\n      this.deferred = Utils.createPromise();\n    }\n\n    const node = new Node({\n      name: commandName,\n      parent: this.currentNode,\n      namespace,\n      stackTrace,\n      deferred,\n      isES6Async,\n      rejectPromise,\n      compatMode,\n      addedInsideCallback: parentContext && parentContext.addedInsideCallback\n    });\n\n    if (this.currentNode.instance && this.currentNode.instance.isES6AsyncCommand) {\n      node.isES6Async = true;\n    }\n\n    node.setCommand(commandFn, context, args, options);\n\n    const initialChildNode = this.shouldStartQueue();\n\n    if (context && context.module && context.module.autoInvoke) {\n      return node;\n    }\n\n    this.tree.addNode(node);\n\n    if (this.currentNode.done || !this.currentNode.started || initialChildNode) {\n      this.scheduleTraverse();\n    }\n\n    return node;\n  }\n\n  scheduleTraverse() {\n    if (this.scheduleTimeoutId) {\n      clearTimeout(this.scheduleTimeoutId);\n    }\n\n    this.scheduleTimeoutId = setTimeout(() => this.traverse(), 0);\n  }\n\n  clearScheduled() {\n    if (this.scheduleTimeoutId) {\n      clearTimeout(this.scheduleTimeoutId);\n    }\n  }\n\n  empty() {\n    this.tree.empty();\n\n    return this;\n  }\n\n  reset() {\n    this.tree.reset();\n\n    return this;\n  }\n\n  traverse() {\n    this.tree\n      .traverse()\n      .catch(err => {\n        return err;\n      })\n      .then(err => {\n        const args = [];\n        if (err instanceof Error) {\n          //Logger.error(err);\n          args.push(err);\n        }\n\n        this.done.apply(this, args);\n      });\n\n    return this;\n  }\n\n  get inProgress() {\n    return this.tree.rootNode.childNodes.length > 0;\n  }\n\n  done(err) {\n    if (this.tree.rootNode.childNodes.length > 0) {\n      return this;\n    }\n\n    err = err || this.tree.returnError;\n\n    this.emit('queue:finished', err);\n    // when using third-party test runners (e.g. cucumber), sometimes the previous error is not cleared\n    this.tree.returnError = null;\n\n    if (this.deferred) {\n      this.deferred.resolve(err);\n      this.deferred = null;\n    }\n  }\n\n  waitForCompletion() {\n    if (this.deferred) {\n      return this.deferred.promise;\n    }\n\n    return Promise.resolve();\n  }\n\n  run(currentTestCaseResult) {\n    this.tree.currentTestCaseResult = currentTestCaseResult;\n    if (this.tree.started) {\n      return this;\n    }\n\n    if (!this.deferred) {\n      this.deferred = Utils.createPromise();\n    }\n    this.scheduleTraverse();\n\n    return this.deferred.promise;\n  }\n}\n\nmodule.exports = CommandQueue;\n"
  },
  {
    "path": "lib/core/treenode.js",
    "content": "const EventEmitter = require('events');\nconst Utils = require('../utils');\nconst Debuggability = require('../utils/debuggability');\n\nclass TreeNode {\n  get command() {\n    return this.__command;\n  }\n\n  get context() {\n    return this.__context;\n  }\n\n  get args() {\n    return this.__args;\n  }\n\n  get instance() {\n    return this.__instance;\n  }\n\n  get redact() {\n    return !!this.options.redact;\n  }\n\n  get isTraceable() {\n    return this.options && this.options.isTraceable;\n  }\n\n  get fullName() {\n    if (!this.namespace || !Utils.isString(this.namespace)) {\n      return this.name;\n    }\n\n    return `${this.namespace}.${this.name}`;\n  }\n\n  get isRootNode() {\n    return this.name === '__root__';\n  }\n\n  /**\n   *\n   * @param {function} commandFn\n   * @param {object} context\n   * @param {Array} args\n   * @param {object} options\n   */\n  setCommand(commandFn, context, args, options = {}) {\n    this.__command = commandFn;\n    this.__context = context;\n    this.__args = args;\n    this.options = options;\n  }\n\n  /**\n   * @param {{name, namespace, stackTrace, parent, deferred}} opts\n   */\n  constructor({name, parent, namespace, stackTrace, deferred, isES6Async, compatMode, rejectPromise, addedInsideCallback}) {\n    this.__command = null;\n    this.__context = null;\n    this.__args = null;\n    this.__instance = null;\n\n    // if we have an ES6 async/await testcase, there will be a deferred object containing the promise\n    this.deferred = deferred || Utils.createPromise();\n    this.isES6Async = deferred !== undefined && (isES6Async || parent.isES6Async);\n    this.name = name || '__root__';\n    this.namespace = namespace;\n    if (Utils.isFunction(this.namespace)) {\n      this.namespace = this.namespace();\n    }\n    this.stackTrace = stackTrace;\n    this.parent = parent;\n    this.compatMode = compatMode;\n\n    this.childNodes = [];\n    this.started = false;\n    this.rejectPromise = rejectPromise;\n    this.done = false;\n    this.startTime = null;\n    this.promiseSettled = false;\n    this.addedInsideCallback = addedInsideCallback;\n  }\n\n  getResult(result) {\n    if (!this.compatMode && Utils.isObject(result) && !Utils.isUndefined(result.status) && !Utils.isUndefined(result.value)) {\n      return result.value;\n    }\n\n    return result;\n  }\n\n  resolve(result) {\n    if (this.promiseSettled || !this.deferred) {\n      return;\n    }\n\n    this.promiseSettled = true;\n    this.deferred.resolve(this.getResult(result));\n  }\n\n  reject(reason) {\n    if (this.promiseSettled || !this.deferred) {\n      return;\n    }\n\n    this.promiseSettled = true;\n    this.deferred.reject(reason);\n  }\n\n  run() {\n    return this.runCommand();\n  }\n\n  handleError(err) {\n    // Set abortOnFailure to false when command is being executed in debugMode\n    if (Debuggability.debugMode) {\n      err.abortOnFailure = false;\n    } else {\n      err.abortOnFailure = err.abortOnFailure || err.abortOnFailure === undefined;\n    }\n\n    const errorName = err.name !== 'Error' ? `[${err.name}] ` : '';\n    const originalError = `${errorName}${err.message}`;\n\n    if (this.stackTrace && Utils.shouldReplaceStack(err)) {\n      err.stack = this.stackTrace;\n    }\n\n    if (err.name !== 'NightwatchAssertError' && err.name !== 'NightwatchMountError') {\n      err.message = `Error while running \"${this.fullName}\" command: ${originalError}`;\n    }\n\n\n    return err;\n  }\n\n  async runCommand() {\n    this.started = true;\n    this.startTime = new Date().getTime();\n\n    let result;\n    try {\n      result = await this.execute();\n    } catch (err) {\n      result = err;\n    }\n\n    this.done = true;\n    this.endTime = new Date().getTime();\n    this.elapsedTime =  this.endTime - this.startTime;\n\n    return result;\n  }\n\n  invokeCommand() {\n    const {args, stackTrace, options, command} = this;\n    command.stackTrace = stackTrace;\n\n    this.__instance = command.call(this.context, {args, stackTrace, options});\n\n    return this.__instance;\n  }\n\n  execute(autoInvoke = false) {\n    const commandFn = this.command;\n    if (!commandFn) {\n      return Promise.resolve();\n    }\n\n    if (autoInvoke) {\n      let result;\n      try {\n        result = this.invokeCommand();\n      } catch (err) {\n        result = err;\n      }\n\n      return result;\n    }\n\n    return new Promise((resolve) => {\n      this.invokeCommand();\n\n      if (this.instance instanceof Promise) {\n        this.instance\n          .then(result => resolve(result))\n          .catch(err => resolve(err));\n\n        return;\n      }\n\n      this.handleCommandResult((result) => {\n        resolve(result);\n      }, (err) => {\n        resolve(err);\n      });\n    });\n  }\n\n  handleCommandResult(resolveFn, rejectFn) {\n    let commandResult;\n\n    if (this.instance instanceof EventEmitter) {\n      commandResult = this.instance;\n      if (this.instance.needsPromise) {\n        this.needsPromise = true;\n        // this change was done because the only way function-styled custom commands could be resolved\n        // is if they contain another NW API command, which could call `node.context.emit('complete')`\n        // inside `asynctree.js > resolveNode` method for the custom command node.\n        commandResult = this.context;\n      }\n    } else if (this.context instanceof EventEmitter) { // Chai assertions\n      commandResult = this.context;\n      // this is for when the command is not emitting an event itself, but has child nodes that may do,\n      //  so when all the child nodes will finish, the parent will also finish\n      this.needsPromise = true;\n    }\n\n    if (!commandResult) {\n      rejectFn(new Error('Commands must either return an EventEmitter which emits a \"complete\" event or a Promise.'));\n\n      return;\n    }\n\n    const completeHandler =  result => {\n      commandResult.removeListener('error', errorHandler);\n      resolveFn(result);\n    };\n\n    const errorHandler = (err, abortOnFailure) => {\n      err.abortOnFailure = abortOnFailure || abortOnFailure === undefined;\n      commandResult.removeListener('complete', completeHandler);\n      rejectFn(err);\n    };\n\n    commandResult.once('complete', completeHandler);\n    commandResult.once('error', errorHandler);\n  }\n}\n\nmodule.exports = TreeNode;\n"
  },
  {
    "path": "lib/element/appium-locator.js",
    "content": "const {By, RelativeBy} = require('selenium-webdriver');\n\nconst LocateElement = require('./locator.js');\nconst LocateStrategy = require('./strategy.js');\n\nclass AppiumLocator extends LocateElement {\n  /**\n   * @param {object|string} element\n   * @return {By|RelativeBy}\n   */\n  static create(element) {\n    if (!element) {\n      throw new Error(`Error while trying to locate element: missing element definition; got: \"${element}\".`);\n    }\n\n    const byInstance = LocateElement.locateInstanceOfBy(element);\n    if (byInstance !== null) {\n      return byInstance;\n    }\n\n    const elementInstance = LocateElement.createElementInstance(element);\n\n    LocateStrategy.validate(elementInstance.locateStrategy);\n\n    return new By(elementInstance.locateStrategy, elementInstance.selector);\n  }\n}\n\nmodule.exports = AppiumLocator;\n"
  },
  {
    "path": "lib/element/command.js",
    "content": "const EventEmitter = require('events');\nconst {WebElement} = require('selenium-webdriver');\n\nconst Utils = require('../utils');\nconst LocateStrategy = require('./strategy.js');\nconst Element = require('./index.js');\nconst {NoSuchElementError} = require('./locator.js');\nconst {Logger, PeriodicPromise, isDefined} = Utils;\n\nclass ElementCommand extends EventEmitter {\n  static isSelectorObject(obj) {\n    return Utils.isObject(obj) && obj.selector;\n  }\n\n  static get ELEMENT_COMMAND_ARGS() {\n    return 3;\n  }\n\n  get api() {\n    return this.nightwatchInstance.api;\n  }\n\n  get client() {\n    return this.nightwatchInstance;\n  }\n\n  get settings() {\n    return this.nightwatchInstance.settings;\n  }\n\n  get transport() {\n    return this.nightwatchInstance.transport;\n  }\n\n  get desiredCapabilities() {\n    return this.nightwatchInstance.session.desiredCapabilities;\n  }\n\n  get reporter() {\n    return this.nightwatchInstance.reporter;\n  }\n\n  get commandName() {\n    return this.__commandName;\n  }\n\n  get defaultUsing() {\n    return this.nightwatchInstance.locateStrategy || LocateStrategy.getDefault();\n  }\n\n  get strategy() {\n    return this.__strategy;\n  }\n\n  get elementLocator() {\n    return this.nightwatchInstance.elementLocator;\n  }\n\n  get rescheduleInterval() {\n    return this.__rescheduleIntervalMs;\n  }\n\n  get ms() {\n    return this.__timeoutMs;\n  }\n\n  get retryOnSuccess() {\n    return false;\n  }\n\n  get retryOnValidActionResult() {\n    return false;\n  }\n\n  get callback() {\n    return this.__callback;\n  }\n\n  get element() {\n    return this.__element;\n  }\n\n  get selector() {\n    return this.__selector;\n  }\n\n  get extraArgsCount() {\n    return null;\n  }\n\n  get abortOnFailure() {\n    return this.__abortOnFailure;\n  }\n\n  set abortOnFailure(value) {\n    this.__abortOnFailure = Utils.convertBoolean(value);\n  }\n\n  get suppressNotFoundErrors() {\n    return this.__suppressNotFoundErrors;\n  }\n\n  set suppressNotFoundErrors(value) {\n    this.__suppressNotFoundErrors = Utils.convertBoolean(value);\n  }\n\n  /**\n   * @override\n   * @returns {*}\n   */\n  protocolAction() {\n    return Promise.resolve();\n  }\n\n  isResultSuccess(result) {\n    return this.transport.isResultSuccess(result) && result.value !== null;\n  }\n\n  protocolActionHandler() {\n    return Promise.resolve();\n  }\n\n  constructor({nightwatchInstance, commandName, args, requireValidation = true} = {}) {\n    super();\n\n    this.nightwatchInstance = nightwatchInstance || this.client; //custom commands don't get the nightwatchInstance\n    this.__commandName = commandName || this.commandFileName;\n\n    this.transport.registerLastError(null);\n    this.setStrategy();\n\n    this.suppressNotFoundErrors = false;\n    this.abortOnFailure = this.api.globals.abortOnAssertionFailure;\n    this.throwOnMultipleElementsReturned = this.api.globals.throwOnMultipleElementsReturned;\n    this.elementId = null;\n    this.args = Array.isArray(args) && args.slice(0) || this.commandArgs || [];\n\n    this.setMilliseconds();\n    this.setRescheduleInterval();\n    this.setArguments(requireValidation);\n    this.setOptionsFromSelector();\n    this.createElement();\n\n    this.setupExecutor();\n    this.setupActions();\n  }\n\n  setupExecutor() {\n    this.executor = new PeriodicPromise({\n      rescheduleInterval: this.rescheduleInterval,\n      timeout: this.ms\n    });\n  }\n\n  setupActions() {\n  }\n\n  command() {\n    return this.executor.run();\n  }\n\n  /**\n   * @override\n   * @param [response]\n   * @returns {*}\n   */\n  elementFound(response) {\n    if (response) {\n      if (this.isSeleniumWebElement(response.value)) {\n        this.webElement = response.value;\n      } else if (isDefined(response.value)) {\n        this.elementId = this.transport.getElementId(response.value);\n      } else {\n        this.elementId = response;\n      }\n    }\n\n    return this.protocolAction();\n  }\n\n  isSeleniumWebElement(value) {\n    return (value instanceof WebElement);\n  }\n  /**\n   * @override\n   * @param err\n   * @returns {ElementCommand}\n   */\n  elementNotFound(err) {\n    return this.complete(err, err.result);\n  }\n\n  elementLocateError(err) {\n    if (err instanceof NoSuchElementError) {\n      return this.elementNotFound(err);\n    }\n\n    Logger.error(err);\n\n    return this.complete(err, {});\n  }\n\n  async findElement({returnSingleElement = true, cacheElementId = true} = {}) {\n    const {element, commandName, WebdriverElementId} = this;\n\n    try {\n      if (WebdriverElementId) {\n        return {\n          value: this.transport.toElement(WebdriverElementId),\n          status: 0,\n          result: {}\n        };\n      }\n\n      return await this.elementLocator.findElement({element, commandName, returnSingleElement, cacheElementId});\n    } catch (err) {\n      if (err.name === 'ReferenceError' || err.name === 'TypeError') {\n        throw err;\n      }\n\n      throw this.noSuchElementError(err);\n    }\n  }\n\n  executeProtocolAction(actionName, args = []) {\n    const {sessionId} = this;\n    let {elementId, webElement, selector} = this;\n\n    if (webElement) {\n      elementId = webElement;\n    } else if (selector instanceof WebElement) {\n      elementId = selector;\n    }\n\n    return this.transport.executeProtocolAction({actionName, args: [elementId, ...args], sessionId});\n  }\n\n  async complete(err, response) {\n    try {\n      await this.callback.call(this.api, response, this);\n\n      if (err instanceof Error) {\n        return err;\n      }\n\n      return response;\n    } catch (cbErr) {\n      return cbErr;\n    }\n  }\n\n  validateArgsCount(requireValidation = true) {\n    if (!requireValidation) {\n      return this;\n    }\n\n    ////////////////////////////////////////////////////////////////////////////\n    // if there is an element command such as getText, getAttribute etc., verify if the\n    // expected number of args have been supplied\n    ////////////////////////////////////////////////////////////////////////////\n    if (this.args.length && !Utils.isFunction(this.args[this.args.length - 1])) {\n      this.args.push(function() {});\n    }\n\n    if (this.extraArgsCount !== null) {\n      let expectedArgs = ElementCommand.ELEMENT_COMMAND_ARGS + this.extraArgsCount;\n      let passedArgs = this.args.length;\n      let rejectPromise;\n\n      if (this.client.isES6AsyncTestcase) {\n        expectedArgs = expectedArgs - 1;\n        passedArgs = passedArgs - 1;\n        rejectPromise = true;\n      }\n\n      if (passedArgs < expectedArgs - 1 || passedArgs > expectedArgs) {\n        const error = new Error(`${this.commandName} method expects ${(expectedArgs - 1)} ` +\n          `(or ${expectedArgs} if using implicit \"css selector\" strategy) arguments - ${passedArgs} given.`);\n        error.rejectPromise = rejectPromise;\n\n        throw error;\n      }\n\n      if (Utils.isString(this.args[0]) && (expectedArgs === passedArgs || ElementCommand.isSelectorObject(this.args[1]))) {\n        this.setStrategyFromArgs();\n      }\n    }\n  }\n\n  setStrategyFromArgs() {\n    const strategy = this.args.shift();\n    LocateStrategy.validate(strategy, this.commandName);\n\n    this.setStrategy(strategy);\n  }\n\n  setArguments(requireValidation) {\n    this.validateArgsCount(requireValidation);\n\n    this.__selector = this.args.shift();\n\n    this.setOutputMessage();\n    this.setCallback();\n\n    return this;\n  }\n\n  setOptionsFromSelector() {\n    if (Utils.isObject(this.selector)) {\n      const {\n        abortOnFailure, retryInterval, message, timeout, locateStrategy, suppressNotFoundErrors, retryAction\n      } = this.selector;\n\n      if (!Utils.isUndefined(abortOnFailure)) {\n        this.abortOnFailure = abortOnFailure;\n      }\n\n      if (!Utils.isUndefined(suppressNotFoundErrors)) {\n        this.suppressNotFoundErrors = suppressNotFoundErrors;\n      }\n\n      if (!Utils.isUndefined(retryInterval)) {\n        this.setRescheduleInterval(retryInterval);\n      }\n\n      if (message) {\n        this.message = message;\n      }\n\n      if (locateStrategy) {\n        this.setStrategy(locateStrategy);\n      }\n\n      if (!Utils.isUndefined(timeout)) {\n        this.setMilliseconds(timeout);\n      }\n\n      if (!Utils.isUndefined(retryAction)) {\n        this.__retryOnFailure = retryAction;\n      }\n\n      const {WebdriverElementId} = this.selector;\n      if (WebdriverElementId) {\n        this.WebdriverElementId = WebdriverElementId;\n      }\n    }\n\n    return this;\n  }\n\n  setStrategy(val = this.defaultUsing) {\n    this.__strategy = val;\n\n    return this;\n  }\n\n  setOutputMessage() {\n    this.message = null;\n    if (this.args.length > 0) {\n      if (Utils.isString(this.args[this.args.length - 1])) {\n        this.message = this.args.pop();\n      }\n    }\n\n    return this;\n  }\n\n  setCallback() {\n    let callback = null;\n    if (this.args.length && Utils.isFunction(this.args[this.args.length - 1])) {\n      callback = this.args.pop();\n    }\n\n    this.__callback = callback || function() {};\n\n    return this;\n  }\n\n  /**\n   * @returns {ElementCommand}\n   */\n  createElement() {\n    this.__element = Element.createFromSelector(this.selector, this.strategy);\n\n    return this;\n  }\n\n  /**\n   * Set the time in milliseconds to wait for the condition, accepting a given value or a globally defined default\n   *\n   * @param {number} [timeoutMs]\n   */\n  setMilliseconds(timeoutMs = this.api.globals.waitForConditionTimeout) {\n    try {\n      Utils.enforceType(timeoutMs, Utils.PrimitiveTypes.NUMBER);\n    } catch (err) {\n      throw new Error('waitForElement expects second parameter to have a global default (waitForConditionTimeout) ' +\n        'to be specified if not passed as the second parameter');\n    }\n\n    this.__timeoutMs = timeoutMs;\n\n    return this;\n  }\n\n  setRescheduleInterval(intervalMs = this.api.globals.waitForConditionPollInterval) {\n    Utils.enforceType(intervalMs, Utils.PrimitiveTypes.NUMBER);\n    this.__rescheduleIntervalMs = intervalMs;\n\n    return this;\n  }\n\n  noSuchElementError(err) {\n    const {element, ms, abortOnFailure} = this;\n    const {retries} = err;\n\n    return new NoSuchElementError({element, ms, abortOnFailure, retries});\n  }\n}\n\nmodule.exports = ElementCommand;\n"
  },
  {
    "path": "lib/element/index.js",
    "content": "const {WebElement, By, RelativeBy} = require('selenium-webdriver');\nconst LocateStrategy = require('./strategy.js');\nconst Utils = require('../utils');\n\nclass Element {\n  static get defaultProps() {\n    return [\n      'name',\n      'parent',\n      'selector',\n      'locateStrategy',\n      'index',\n      'abortOnFailure',\n      'suppressNotFoundErrors',\n      'timeout',\n      'retryInterval',\n      'message',\n      'pseudoSelector'\n    ];\n  }\n\n  /**\n   * Class that all elements subclass from.\n   *\n   * @param {Object} definition User-defined element options defined in page object.\n   * @param {Object} [options] Additional options to be given to the element.\n   * @constructor\n   */\n  constructor(definition, options = {}) {\n    this.name = options.name;\n\n    this.setProperties(definition, options);\n\n    this.parent = options.parent;\n    this.resolvedElement = null;\n  }\n\n  get index() {\n    return parseInt(this.__index, 10);\n  }\n\n  set index(val) {\n    this.__index = val;\n  }\n\n  get indexDisplay() {\n    return isNaN(this.index) ? '' : `[${this.index}]`;\n  }\n\n  get usingRecursion() {\n    return this.locateStrategy === LocateStrategy.Recursion;\n  }\n\n  set selector(val) {\n    this.__selector = val;\n  }\n\n  get selector() {\n    if (Utils.isString(this.__selector) && this.pseudoSelector && !this.__selector.includes(':')) {\n      return `${this.__selector}:${this.pseudoSelector}`;\n    }\n\n    return this.__selector;\n  }\n\n  setProperties(definition, options) {\n    if (definition.webElement instanceof WebElement) {\n      this.webElement = definition.webElement;\n    } else if (definition.webElementId) {\n      this.webElementId = definition.webElementId;\n    } else if (!definition.selector) {\n      throw new Error(`No selector property for ${getDescription(this)}. Instead found properties: ` +\n        Object\n          .keys(definition)\n          .filter(hasValidValueIn(definition))\n          .join(', ')\n      );\n    }\n\n    this.__index = definition.index;\n    this.__selector = definition.selector;\n\n    const locateStrategyFromParent = options.parent ? options.parent.client.configLocateStrategy : undefined;\n    this.locateStrategy = definition.locateStrategy || options.locateStrategy || locateStrategyFromParent || LocateStrategy.getDefault();\n\n    this.pseudoSelector = null;\n\n    if (!Utils.isUndefined(definition.abortOnFailure)) {\n      this.abortOnFailure = Utils.convertBoolean(definition.abortOnFailure);\n    }\n\n    if (!Utils.isUndefined(definition.suppressNotFoundErrors)) {\n      this.suppressNotFoundErrors = Utils.convertBoolean(definition.suppressNotFoundErrors);\n    }\n\n    if (!Utils.isUndefined(definition.retryInterval)) {\n      this.retryInterval = definition.retryInterval;\n    }\n\n    if (definition.message) {\n      this.message = definition.message;\n    }\n\n    if (!Utils.isUndefined(definition.timeout)) {\n      this.timeout = definition.timeout;\n    }\n  }\n\n  getId() {\n    return this.resolvedElement;\n  }\n\n  setResolvedElement(value) {\n    this.resolvedElement = value;\n  }\n\n  toString() {\n    if (Array.isArray(this.selector)) { // recursive\n      return this.selector.join(',');\n    }\n\n    if (!this.name) { // inline (not defined in page or section)\n      if (this.selector) {\n        return this.selector;\n      }\n      if (this.webElement instanceof WebElement) {\n        return `web element{${this.resolvedElement}}`;\n      }\n\n      return 'unknown selector';\n    }\n\n    let classType = this.constructor.name;\n    let prefix = this.constructor === Element ? '@' : '';\n\n    return `${classType} [name=${prefix}${this.name}${this.indexDisplay}]`;\n  }\n\n  /**\n   * Determines whether or not the element contains an @ element reference\n   * for its selector.\n   *\n   * @returns {boolean} True if the selector is an element reference starting with an\n   *    @ symbol, false if it does not.\n   */\n  hasElementSelector() {\n    return String(this.selector).charAt(0) === '@';\n  }\n\n  /**\n   * If the element object requires a recursive lookup to resolve its\n   * selector, a new element containing the recursive lookup values\n   * is created and returned.\n   *\n   * @returns {Object} A new Element object containing the element and its\n   *    parents with a recursive lookup strategy for resolving the element\n   *    if one is needed. If not, null is returned.\n   */\n  getRecursiveLookupElement() {\n    let lookupList = getAncestorsWithElement(this);\n\n    if (lookupList.length > 1) {\n      return new Element({\n        selector: lookupList,\n        locateStrategy: LocateStrategy.Recursion,\n        abortOnFailure: this.abortOnFailure,\n        timeout: this.timeout,\n        retryInterval: this.retryInterval,\n        message: this.message\n      });\n    }\n\n    return null;\n  }\n\n  /**\n   * Copies selector properties to the first object from the second if the first\n   * object has undefined or null values for any of those properties.\n   *\n   * @param {Object} target The object to assign values to.\n   * @param {Object} source The object to capture values from.\n   */\n  static copyDefaults(target, source) {\n    Element.defaultProps.forEach(function(prop) {\n      if (target[prop] === undefined || target[prop] === null || isNaN(target[prop]) && !isNaN(source[prop])) {\n        target[prop] = source[prop];\n      }\n    });\n  }\n\n  /**\n   * Parses the value/selector parameter of an element command creating a\n   * new Element instance with the values it contains, if any. The standard\n   * format for this is a selector string, but additional, complex formats\n   * in the form of an array or object are also supported.\n   *\n   * @param {string|Object|Element} value Selector value to parse into an Element.\n   * @param {string} [using] The using/locateStrategy to use if the selector\n   *    doesn't provide one of its own.\n   */\n  static createFromSelector(value, using) {\n    if (!value) {\n      throw new Error(`Invalid selector value specified \"${value}\"`);\n    }\n\n    if ((value instanceof Element) && value.selector) {\n      if (!value.locateStrategy) {\n        value.locateStrategy = using;\n      }\n\n      return value;\n    }\n\n    if (value instanceof Promise) {\n      value['@nightwatch_element'] = true;\n    }\n\n    if (value['@nightwatch_element']) {\n      return value;\n    }\n\n    let definition;\n    let options;\n    if ((value instanceof Element) && (value.webElement instanceof WebElement)) {\n      return value;\n    }\n\n    if (WebElement.isId(value)) {\n      definition = {\n        webElementId: value\n      };\n    } else if (value instanceof WebElement) {\n      definition = {\n        webElement: value\n      };\n    } else if (value instanceof RelativeBy) {\n      definition = {\n        selector: value\n      };\n    } else if (value instanceof By) {\n      definition = {\n        selector: value.value,\n        locateStrategy: value.using\n      };\n    } else {\n      options = {\n        locateStrategy: using\n      };\n\n      if (using !== LocateStrategy.Recursion && Utils.isObject(value)) {\n        definition = value;\n      } else {\n        definition = {\n          selector: value\n        };\n      }\n    }\n\n    return new Element(definition, options);\n  }\n\n  /**\n   * Returns true when an elements() request is needed to capture\n   * the result of the Element definition.  When false, it means the\n   * Element targets the first result the selector match meaning an\n   * element() (single match only) result can be used.\n   *\n   * @param {Element} element The Element instance to check to see if\n   *    it will apply filtering.\n   */\n  static requiresFiltering(element) {\n    return !isNaN(element.index);\n  }\n\n  /**\n   * Filters an elements() results array to a more specific set based\n   * on an Element object's definition.\n   *\n   * @param {Element} element The Element instance to check to see if\n   *    it will apply filtering.\n   * @param {Array} resultElements Array of WebElement JSON objects\n   *    returned from a call to elements() or elementIdElements().\n   * @return {Array} A filtered version of the elements array or, if\n   *    the filter failed (no matches found) null.\n   */\n  static applyFiltering(element, resultElements) {\n    if (Element.requiresFiltering(element)) {\n      let foundElem = resultElements[element.index];\n\n      return foundElem ? [foundElem] : null; // null = not found\n    }\n\n    return resultElements;\n  }\n\n  static isElementObject(element) {\n    return (element instanceof Element) || (element instanceof WebElement) || (element instanceof By) || WebElement.isId(element);\n  }\n}\n\n/**\n * Array filter method removing elements that may be defined (in) but\n * do not have a recognizable value.\n */\nfunction hasValidValueIn(definition) {\n  return function(key) {\n    return definition[key] !== undefined && definition[key] !== null;\n  };\n}\n\n/**\n * Retrieves an array of ancestors of the supplied element. The last element in the array is the element object itself\n *\n * @param {Object} element The element\n * @returns {Array}\n */\nfunction getAncestorsWithElement(element) {\n  let elements = [];\n\n  function addElement(e) {\n    elements.unshift(e);\n    if (e.parent && e.parent.selector) {\n      addElement(e.parent);\n    }\n  }\n\n  addElement(element);\n\n  return elements;\n}\n\n/**\n * Gets a simple description of the element based on whether or not\n * it is used as an inline selector in a command call or a definition\n * within a page object or section.\n */\nfunction getDescription(instance) {\n  if (instance.name) {\n    let classType = instance.constructor.name.toLowerCase(); // Element, Section or any other subclass's name\n\n    return `${classType} \"${instance.name}\"`;\n  }\n\n  return 'selector object';\n}\n\nmodule.exports = Element;\nmodule.exports.LocateStrategy = LocateStrategy;\nmodule.exports.Command = require('./command.js');\nmodule.exports.Locator = require('./locator.js');\n"
  },
  {
    "path": "lib/element/locate/elements-by-recursion.js",
    "content": "const RecursiveLookupBase = require('./recursive-lookup.js');\n\n/**\n * Search for multiple elements on the page, starting with the first element of the array,\n *  and where each element in the passed array is nested under the previous one.\n * The located element will be returned as a WebElement JSON object.\n *\n * @param {Array} elements An array of ancestor element objects containing selector and locateStrategy properties\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol\n */\n\nclass MultipleElementsByRecursion extends RecursiveLookupBase {\n  get transportAction() {\n    return 'locateMultipleElementsByElementId';\n  }\n\n  get commandName() {\n    return 'elementIdElements';\n  }\n\n  locateElements({element, returnSingleElement}) {\n    this.allElements = Array.isArray(element.selector) ? element.selector.slice() : [\n      element\n    ];\n    const nextElement = this.getNextElement();\n\n    this.elementLocator\n      .findElement({element: nextElement, cacheElementId: false, returnSingleElement: this.shouldReturnSingleElement(returnSingleElement)})\n      .then(result => {\n        if (result.value === null) {\n          this.deferred.resolve(result);\n        } else {\n          this.recursiveElementLookup({result, returnSingleElement});\n        }\n      });\n\n    return this.deferred.promise;\n  }\n}\n\n\nmodule.exports = MultipleElementsByRecursion;\n"
  },
  {
    "path": "lib/element/locate/recursive-lookup.js",
    "content": "const EventEmitter = require('events');\nconst Utils = require('../../utils');\n\n/**\n * Search for an element on the page, starting with the first element of the array, and where each element in the passed array is nested under the previous one. The located element will be returned as a WebElement JSON object.\n *\n * @param {Array} elements An array of ancestor element objects containing selector and locateStrategy properties\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol\n */\nclass RecursiveLookupBase extends EventEmitter {\n  constructor(nightwatchInstance) {\n    super();\n\n    this.elementLocator = nightwatchInstance.elementLocator;\n    this.transport = nightwatchInstance.transport;\n    this.createPromise();\n  }\n\n  getNextElement() {\n    return this.allElements.shift();\n  }\n\n  createPromise() {\n    this.deferred = Utils.createPromise();\n\n    return this;\n  }\n\n  /**\n   * In case we need a collection of elements, we only need to retrieve it if it's the last request from\n   *  the recursive locate chain\n   * @param {Boolean} returnSingleElement\n   * @return {Boolean}\n   */\n  shouldReturnSingleElement(returnSingleElement) {\n    if (!returnSingleElement && this.allElements.length > 0) {\n      return true;\n    }\n\n    return returnSingleElement;\n  }\n\n  recursiveElementLookup({result, returnSingleElement}) {\n    let element = this.getNextElement();\n\n    if (element) {\n      this.elementLocator.findElement({\n        id: this.transport.getElementId(Utils.isDefined(result.value) ? result.value : result),\n        element,\n        transportAction: this.transportAction,\n        commandName: this.commandName,\n        returnSingleElement: this.shouldReturnSingleElement(returnSingleElement),\n        cacheElementId: false\n      })\n        .then(result => {\n          this.recursiveElementLookup({\n            result,\n            returnSingleElement\n          });\n        })\n        .catch(result => {\n          this.deferred.reject(result);\n        });\n    } else {\n      if (result.error instanceof Error) {\n        this.deferred.reject(result.error);\n\n        return;\n      }\n\n      this.deferred.resolve(result);\n    }\n  }\n\n  /**\n   *\n   * @param {string|object} result\n   * @param {function} callback\n   * @return {Promise}\n   */\n  complete(result, callback) {\n    callback(result);\n    this.emit('complete');\n\n    return result;\n  }\n}\n\n\nmodule.exports = RecursiveLookupBase;\n"
  },
  {
    "path": "lib/element/locate/single-element-by-recursion.js",
    "content": "const RecursiveLookupBase = require('./recursive-lookup.js');\n\n/**\n * Search for an element on the page, starting with the first element of the array, and where each element in the passed array is nested under the previous one. The located element will be returned as a WebElement JSON object.\n *\n * @param {Array} elements An array of ancestor element objects containing selector and locateStrategy properties\n * @param {function} [callback] Optional callback function to be called when the command finishes.\n * @api protocol\n */\nclass SingleElementByRecursion extends RecursiveLookupBase {\n  get transportAction() {\n    return 'locateSingleElementByElementId';\n  }\n\n  get commandName() {\n    return 'elementIdElement';\n  }\n  /**\n   *\n   * @param {Array} elements\n   * @return {Promise}\n   */\n  locateElement(elements) {\n    this.allElements = elements.slice();\n    const element = this.getNextElement();\n\n    this.elementLocator\n      .findElement({element})\n      .then(result => {\n        this.recursiveElementLookup({result});\n      });\n\n    return this.deferred.promise;\n  }\n}\n\n\nmodule.exports = SingleElementByRecursion;\n"
  },
  {
    "path": "lib/element/locator-factory.js",
    "content": "const {By, RelativeBy} = require('selenium-webdriver');\n\nconst Locator = require('./locator.js');\nconst AppiumLocator = require('./appium-locator.js');\n\nclass NightwatchLocator {\n  /**\n   * @param {object|string} element\n   * @param {boolean} isAppiumClient\n   * @return {By|RelativeBy}\n   */\n  static create(element, isAppiumClient) {\n    if (isAppiumClient) {\n      return AppiumLocator.create(element);\n    }\n\n    return Locator.create(element);\n  }\n}\n\nmodule.exports = NightwatchLocator;\n"
  },
  {
    "path": "lib/element/locator.js",
    "content": "const {By, RelativeBy, until} = require('selenium-webdriver');\nconst Element = require('./index.js');\nconst ElementsByRecursion = require('./locate/elements-by-recursion.js');\nconst SingleElementByRecursion = require('./locate/single-element-by-recursion.js');\n\nconst AVAILABLE_LOCATORS = {\n  'css selector': 'css',\n  'id': 'id',\n  'link text': 'linkText',\n  'name': 'name',\n  'partial link text': 'partialLinkText',\n  'tag name': 'tagName',\n  'xpath': 'xpath',\n  'className': 'className'\n};\n\nclass LocateElement {\n  /**\n   * @param {object|string} element\n   * @return {By|RelativeBy}\n   */\n  static create(element) {\n    if (!element) {\n      throw new Error(`Error while trying to locate element: missing element definition; got: \"${element}\".`);\n    }\n\n    const byInstance = LocateElement.locateInstanceOfBy(element);\n    if (byInstance !== null) {\n      return byInstance;\n    }\n\n    const elementInstance = LocateElement.createElementInstance(element);\n\n    return By[AVAILABLE_LOCATORS[elementInstance.locateStrategy]](elementInstance.selector);\n  }\n\n  /**\n   * @param {object} element\n   * @return {By|RelativeBy|null}\n   */\n  static locateInstanceOfBy(element) {\n    if (element instanceof By) {\n      return element;\n    }\n\n    if (element.by instanceof By) {\n      return element.by;\n    }\n\n    if (element.value instanceof RelativeBy) {\n      return element.value;\n    }\n\n    return null;\n  }\n\n  /**\n   * @param {object|string} element\n   * @return {Element}\n   */\n  static createElementInstance(element) {\n    if (typeof element != 'object' && typeof element != 'string') {\n      throw new Error(`Invalid element definition type; expected string or object, but got: ${typeof element}.`);\n    }\n\n    let selector;\n    let strategy;\n\n    if (typeof element == 'object' && element.value && element.using) {\n      selector = element.value;\n      strategy = element.using;\n    } else {\n      selector = element;\n    }\n\n    return Element.createFromSelector(selector, strategy);\n  }\n\n  get api() {\n    return this.nightwatchInstance.api;\n  }\n\n  get reporter() {\n    return this.nightwatchInstance.reporter;\n  }\n\n  get settings() {\n    return this.nightwatchInstance.settings;\n  }\n\n  get transport() {\n    return this.nightwatchInstance.transport;\n  }\n\n  get desiredCapabilities() {\n    return this.nightwatchInstance.session.desiredCapabilities;\n  }\n\n  constructor(nightwatchInstance) {\n    this.nightwatchInstance = nightwatchInstance;\n  }\n\n  resolveElementRecursively({element}) {\n    return this.findElement({element}).then(response => {\n      const firstElement = element.selector[element.selector.length - 1];\n      firstElement.resolvedElement = response;\n\n      const {selector, locateStrategy, name} = firstElement;\n      const {status, value} = response;\n      const WebdriverElementId = response && response.WebdriverElementId || null;\n      const result = {\n        selector,\n        locateStrategy,\n        name,\n        WebdriverElementId,\n        response: {\n          status,\n          value\n        }\n      };\n\n      if (!isNaN(firstElement.index)) {\n        result.index = firstElement.index;\n      }\n\n      return result;\n    });\n  }\n\n  /**\n   * Finds a single element by using the multiple locate elements, which instead of throwing an error returns an empty array\n   *\n   * @param {Element} element\n   * @param {String} commandName\n   * @param {String} id\n   * @param {String} transportAction\n   * @param {Boolean} [returnSingleElement]\n   * @param {Boolean} [cacheElementId]\n   * @return {Promise}\n   */\n  async findElement({element, commandName, id, transportAction = 'locateMultipleElements', returnSingleElement = true, cacheElementId = true}) {\n    if (element && (element.webElement || element.webElementId)) {\n      const elementId = await (element.webElement || element.webElementId).getId();\n      element.setResolvedElement(elementId);\n\n      return {\n        value: this.transport.toElement(elementId),\n        status: 0\n      };\n    }\n\n    if (element.resolvedElement && cacheElementId) {\n      return Promise.resolve({\n        value: this.transport.toElement(element.resolvedElement),\n        status: 0\n      });\n    }\n\n    if (element.usingRecursion) {\n      if (transportAction === 'locateSingleElement') {\n        return this.findSingleElementUsingRecursion(element);\n      }\n\n      return this.findElementsUsingRecursion({element, returnSingleElement});\n    }\n\n    const result = await this.executeProtocolAction({element, commandName, id, transportAction, cacheElementId});\n\n    return this.handleLocateElement({result, element, returnSingleElement});\n  }\n\n  locateMultipleElements(element) {\n    const commandName = 'locateMultipleElements';\n    const transportAction = 'locateMultipleElements';\n\n    return this.executeProtocolAction({element, commandName, transportAction});\n  }\n\n  handleLocateElement({result, element, returnSingleElement}) {\n    const {status = 0, error} = result || {};\n    let {value} = result;\n\n    if (error instanceof Error) {\n      return {\n        error,\n        status: -1,\n        value\n      };\n    }\n\n    let WebdriverElementId;\n    const elementResult = this.transport.resolveElement(result, element, true);\n    if (elementResult) {\n      WebdriverElementId = this.transport.getElementId(elementResult);\n      element.setResolvedElement(WebdriverElementId);\n    }\n\n    if (returnSingleElement) {\n      value = elementResult;\n    }\n\n    return {\n      value,\n      status,\n      WebdriverElementId\n    };\n  }\n\n  /**\n   * @returns Promise({{\n   *    value,\n   *    status,\n   *    result,\n   *    now\n   * }})\n   */\n  executeProtocolAction(opts = {}) {\n    const {id, element, transportAction, commandName, cacheElementId} = opts;\n    const args = {\n      id\n    };\n\n    if (element instanceof By) {\n      args.by = element;\n    } else {\n      args.using = element.locateStrategy;\n      args.value = element.selector;\n    }\n\n    return this.sendElementsAction({transportAction, args, element, cacheElementId})\n      .catch(err => {\n        if (this.transport.invalidSessionError(err)) {\n          return new Error(this.transport.getErrorMessage(err));\n        }\n\n        throw err;\n      })\n\n      .then(result => {\n        if (this.transport.isResultSuccess(result) && Element.requiresFiltering(element)) {\n          return this.filterElements(element, result);\n        }\n\n        return result;\n      })\n      // Catch errors from filterElements and from invalid session\n      .catch(error => {\n        return {\n          value: null,\n          status: -1,\n          error\n        };\n      });\n  }\n\n  async sendElementsAction({transportAction, args, element, cacheElementId} = {}) {\n    if (cacheElementId && transportAction === 'locateMultipleElements' && args && !(args.value instanceof RelativeBy)) {\n      const timeout = element.timeout || this.settings.globals.waitForConditionTimeout;\n      const retryInterval = element.retryInterval || this.settings.globals.waitForConditionPollInterval;\n\n      try {\n        const results = await this.transport.driver.wait(until.elementsLocated(args), timeout, null, retryInterval);\n        const {elementKey} = this.transport;\n        const value = await Promise.all(results.map(async webElement => {\n          const elementId = await webElement.getId();\n\n          return {[elementKey]: elementId};\n        }));\n\n        return {\n          status: 0,\n          value\n        };\n      } catch (err) {\n        if (err.name !== 'TimeoutError') {\n          throw err;\n        }\n\n        throw new NoSuchElementError({element, ms: timeout});\n      }\n    }\n\n    return this.transport.executeProtocolAction(transportAction, args);\n  }\n\n  /**\n   * Selects a subset of elements if the result requires filtering.\n   *\n   * @param {Element} element\n   * @param {object} result\n   * @return {*}\n   */\n  filterElements(element, result) {\n    let filtered = Element.applyFiltering(element, result.value);\n\n    if (filtered) {\n      result.value = filtered;\n\n      return result;\n    }\n\n    const errorResult = this.transport.getElementNotFoundResult(result);\n\n    throw new Error(`Element ${element.toString()} not found.${errorResult.message ? (' ' + errorResult.message) : ''}`);\n  }\n\n  /**\n   * @param {Element} element\n   * @param {Boolean} returnSingleElement\n   * @return {Promise}\n   */\n  findElementsUsingRecursion({element, returnSingleElement = true}) {\n    let recursion = new ElementsByRecursion(this.nightwatchInstance);\n\n    return recursion.locateElements({element, returnSingleElement});\n  }\n\n  findSingleElementUsingRecursion(element) {\n    let recursion = new SingleElementByRecursion(this.nightwatchInstance);\n\n    return recursion.locateElement(element.selector);\n  }\n}\n\nclass NoSuchElementError extends Error {\n  constructor({element, ms, abortOnFailure, retries}) {\n    super();\n\n    this.selector = element.selector;\n    this.abortOnFailure = abortOnFailure;\n    this.name = 'NoSuchElementError';\n    this.retries = retries;\n    this.strategy = element.locateStrategy;\n    this.message = `Timed out while waiting for element \"${this.selector}\" with \"${this.strategy}\" to be present for ${ms} milliseconds.`;\n  }\n}\n\nmodule.exports = LocateElement;\nmodule.exports.NoSuchElementError = NoSuchElementError;\nmodule.exports.AVAILABLE_LOCATORS = AVAILABLE_LOCATORS;\n"
  },
  {
    "path": "lib/element/strategy.js",
    "content": "const __RECURSION__ = 'recursion';\n\nclass LocateStrategy {\n  static get Strategies() {\n    return {\n      ID: 'id',\n      CSS_SELECTOR: 'css selector',\n      LINK_TEXT: 'link text',\n      PARTIAL_LINK_TEXT: 'partial link text',\n      TAG_NAME: 'tag name',\n      XPATH: 'xpath',\n      NAME: 'name',\n      CLASS_NAME: 'class name',\n      // Appium-specific strategies\n      ACCESSIBILITY_ID: 'accessibility id',\n      ANDROID_UIAUTOMATOR: '-android uiautomator',\n      IOS_PREDICATE_STRING: '-ios predicate string',\n      IOS_CLASS_CHAIN: '-ios class chain'\n    };\n  }\n\n  static isValid(strategy) {\n    return Object.keys(LocateStrategy.Strategies).some(key => {\n      return String(strategy).toLocaleLowerCase() === LocateStrategy.Strategies[key];\n    });\n  }\n\n  static getList() {\n    return Object.keys(LocateStrategy.Strategies).map(k => LocateStrategy.Strategies[k]).join(', ');\n  }\n\n  static get XPATH() {\n    return LocateStrategy.Strategies.XPATH;\n  }\n\n  static get CSS_SELECTOR() {\n    return LocateStrategy.Strategies.CSS_SELECTOR;\n  }\n\n  static getDefault() {\n    return LocateStrategy.CSS_SELECTOR;\n  }\n\n  static validate(strategy, apiMethod) {\n    if (!LocateStrategy.isValid(strategy)) {\n      const list = LocateStrategy.getList();\n      const forApiMethod  = apiMethod ? ` for .${apiMethod}()` : '';\n\n      throw new Error(`Provided locating strategy \"${strategy}\" is not supported${forApiMethod}. It must be one of the following: ${list}.`);\n    }\n  }\n\n  static get Recursion() {\n    return __RECURSION__;\n  }\n}\n\nmodule.exports = LocateStrategy;\n"
  },
  {
    "path": "lib/http/auth.js",
    "content": "const HttpUtil = require('./http.js');\n\nclass Auth {\n  constructor(httpRequest) {\n    this.httpRequest = httpRequest;\n  }\n\n  basic(user, pass) {\n    return `Basic ${Auth.toBase64(`${user}:${pass}`)}`;\n  }\n\n  addAuth(user, pass) {\n    if (user && pass) {\n      this.httpRequest.setHeader(HttpUtil.Headers.AUTHORIZATION, this.basic(user, pass));\n    }\n  }\n\n  static toBase64(str) {\n    return Buffer.from(str).toString('base64');\n  }\n}\n\nmodule.exports = Auth;\n"
  },
  {
    "path": "lib/http/formatter.js",
    "content": "const {Logger} = require('../utils');\nconst jsonRegex = new RegExp('[\\\\u007f-\\\\uffff]', 'g');\n\nclass ResponseFormatter {\n  /**\n   * Built in JSON.stringify() will return unicode characters that require UTF-8 encoding on the wire.\n   * This function will replace unicode characters with their escaped (ASCII-safe) equivalents to support\n   * the keys sending command.\n   *\n   * @param {object} s\n   * @returns {string}\n   */\n  static jsonStringify(s) {\n    try {\n      const json = JSON.stringify(s);\n      if (json) {\n        return json.replace(jsonRegex, function jsonRegexReplace(c) {\n          return '\\\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4);\n        });\n      }\n\n      return json;\n    } catch (err) {\n\n      Logger.error(err);\n\n      return '';\n    }\n  }\n\n  static stripUnknownChars(str) {\n    const x = [];\n    let i = 0;\n    const length = str.length;\n\n    for (i; i < length; i++) {\n      if (str.charCodeAt(i)) {\n        x.push(str.charAt(i));\n      }\n    }\n\n    return x.join('');\n  }\n\n  static formatHostname(hostname, port, useSSL) {\n    const isLocalHost = ['127.0.0.1', 'localhost'].indexOf(hostname) > -1;\n    const protocol = useSSL ? 'https://' : 'http://';\n    const isPortDefault = [80, 443].indexOf(port) > -1;\n\n    if (isLocalHost) {\n      return '';\n    }\n\n    return protocol + hostname + (!isPortDefault && (':' + port) || '');\n  }\n}\n\nmodule.exports = ResponseFormatter;\n"
  },
  {
    "path": "lib/http/http.js",
    "content": "const ContentTypes = {\n  JSON: 'application/json',\n  JSON_WITH_CHARSET: 'application/json; charset=utf-8',\n  MULTIPART_FORM_DATA: 'multipart/form-data'\n};\n\nconst Headers = {\n  ACCEPT: 'accept',\n  CONTENT_TYPE: 'content-type',\n  CONTENT_LENGTH: 'content-length',\n  AUTHORIZATION: 'authorization'\n};\n\nconst Http = module.exports = {\n  Method: {\n    POST: 'POST',\n    PUT: 'PUT',\n    DELETE: 'DELETE',\n    GET: 'GET'\n  },\n\n  StatusCode: {\n    MOVED_PERMANENTLY: 301,\n    MOVED_TEMPORARILY: 302,\n    SEE_OTHER: 303,\n    NOT_MODIFIED: 304,\n    TEMPORARY_REDIRECT: 307\n  },\n\n  isRedirect(statusCode) {\n    return [\n      Http.StatusCode.MOVED_PERMANENTLY,\n      Http.StatusCode.MOVED_TEMPORARILY,\n      Http.StatusCode.SEE_OTHER,\n      Http.StatusCode.NOT_MODIFIED\n    ].indexOf(statusCode) > -1;\n  },\n\n  needsContentLengthHeader(requestMethod) {\n    return [\n      Http.Method.POST,\n      Http.Method.PUT,\n      Http.Method.DELETE\n    ].indexOf(requestMethod) > -1;\n  },\n\n  Headers: Headers,\n  ContentTypes: ContentTypes\n};\n"
  },
  {
    "path": "lib/http/options.js",
    "content": "const Settings = {\n  SELENIUM_HOST: 'host',\n  SELENIUM_PORT: 'port',\n  CREDENTIALS: 'credentials',\n  PROXY: 'proxy',\n  USE_SSL: 'use_ssl',\n  KEEP_ALIVE: 'keep_alive',\n  DEFAULT_PATH: 'default_path',\n  TIMEOUT: 'timeout',\n  RETRY_ATTEMPTS: 'retry_attempts',\n  INTERNAL_SERVER_ERROR_RETRY_INTERVAL: 'internal_server_error_retry_interval'\n};\n\nclass HttpOptions {\n  #settings;\n\n  get settings() {\n    return this.#settings;\n  }\n\n  constructor() {\n    this.#settings = {};\n  }\n\n  #updateSetting(key, value) {\n    this.#settings[key] = value;\n\n    return this;\n  }\n\n  setPort(port) {\n    this.#updateSetting(Settings.SELENIUM_PORT, port);\n  }\n\n  setHost(value) {\n    this.#updateSetting(Settings.SELENIUM_HOST, value);\n  }\n\n  useSSL(value) {\n    this.#updateSetting(Settings.USE_SSL, value);\n  }\n\n  setKeepAlive(value) {\n    this.#updateSetting(Settings.KEEP_ALIVE, value);\n  }\n\n  setCredentials(credentials) {\n    this.#updateSetting(Settings.CREDENTIALS, credentials);\n  }\n\n  setProxy(proxy) {\n    this.#updateSetting(Settings.PROXY, proxy);\n  }\n\n  setDefaultPathPrefix(path) {\n    this.#updateSetting(Settings.DEFAULT_PATH, path);\n  }\n\n  setTimeout(timeout) {\n    this.#updateSetting(Settings.TIMEOUT, timeout);\n  }\n\n  setRetryAttempts(retryAttempts) {\n    this.#updateSetting(Settings.RETRY_ATTEMPTS, retryAttempts);\n  }\n\n  setInternalServerRetryIntervel(retryInterval) {\n    this.#updateSetting(Settings.INTERNAL_SERVER_ERROR_RETRY_INTERVAL, retryInterval);\n  }\n}\n\nmodule.exports = {\n  global: new HttpOptions(),\n  HttpOptions\n};\n"
  },
  {
    "path": "lib/http/request.js",
    "content": "const EventEmitter = require('events');\nconst http   = require('http');\nconst https  = require('https');\nconst dns = require('dns');\nconst path = require('path');\nconst {Key} = require('selenium-webdriver');\n\nconst HttpUtil = require('./http.js');\nconst HttpOptions = require('./options.js');\nconst Auth = require('./auth.js');\nconst Formatter = require('./formatter.js');\nconst HttpResponse = require('./response.js');\nconst Utils = require('./../utils');\nconst {Logger, isString} = Utils;\nconst {DEFAULT_RUNNER_EVENTS: {LogCreated}, NightwatchEventHub} = require('../runner/eventHub.js');\n\n// To handle Node v17 issue. Refer https://github.com/nodejs/node/issues/40702 for details.\nif (dns.setDefaultResultOrder && (typeof dns.setDefaultResultOrder === 'function')) {\n  dns.setDefaultResultOrder('ipv4first');\n}\n\nconst __defaultSettings__ = {\n  credentials: null,\n  use_ssl: false,\n  proxy: null,\n  timeout: 60000,\n  retry_attempts: 0,\n  internal_server_error_retry_interval: 1000\n};\n\nlet __globalSettings__ = null;\n\nlet __httpKeepAliveAgent__ = null;\n\nclass HttpRequest extends EventEmitter {\n  static get USER_AGENT() {\n    const version = require('../../package.json').version;\n    const platform = ({darwin: 'mac', win32: 'windows'}[process.platform]) || 'linux';\n\n    return `nightwatch.js/${version} (${platform})`;\n  }\n\n  constructor(opts) {\n    super();\n\n    this.__settings = null;\n    this.isAborted = false;\n    this.httpRequest = null;\n    this.httpResponse = null;\n    this.retryCount = 0;\n    this.addtOpts = opts.addtOpts || {};\n    this.auth = null;\n\n    this.setHttpOpts();\n    this.setOptions(opts);\n  }\n\n  static set globalSettings(val) {\n    __globalSettings__ = val;\n  }\n\n  static resetHttpKeepAliveAgents() {\n    __httpKeepAliveAgent__ = null;\n  }\n\n  static getAgent({secure, keepAliveMsecs, maxSockets}) {\n    const expectedProtocol = secure ? 'https:' : 'http:';\n    if (__httpKeepAliveAgent__ && __httpKeepAliveAgent__.protocol === expectedProtocol) {\n      return __httpKeepAliveAgent__;\n    }\n\n    const protocol = secure ? https : http;\n\n    // might also consider storing http and https user agents separately\n    // and use the same agent for the entirety of test instead of creating\n    // a new user-agent every time the protocol changes.\n    // 1st commit: https://github.com/nightwatchjs/nightwatch/pull/3748\n    return __httpKeepAliveAgent__ =  new protocol.Agent({\n      keepAlive: true,\n      keepAliveMsecs,\n      maxSockets\n    });\n  }\n\n  static get globalSettings() {\n    return __globalSettings__ || HttpOptions.global.settings;\n  }\n\n  static updateGlobalSettings(settings = {}) {\n    Object.assign(__globalSettings__, settings);\n  }\n\n  setHttpOpts() {\n    this.__settings = Object.assign({}, __defaultSettings__, HttpRequest.globalSettings);\n  }\n\n  get httpOpts() {\n    return this.__settings;\n  }\n\n  get socket() {\n    return this.httpRequest.socket;\n  }\n\n  get elapsedTime() {\n    return this.httpResponse.elapsedTime;\n  }\n\n  get statusCode() {\n    return this.httpResponse.res.statusCode;\n  }\n\n  setOptions(options) {\n    this.setPathPrefix(options);\n\n    const {method} = options;\n    if (options.data && !(method === 'POST' || method === 'PUT' || method === 'PATCH')) {\n      options.data = '';\n    }\n\n    if (options.multiPartFormData) {\n      this.multiPartFormData = options.multiPartFormData;\n      this.formBoundary = `----NightwatchFormBoundary${Math.random().toString(16).slice(2)}`;\n\n      this.setFormData(this.formBoundary);\n    } else {\n      this.setData(options);\n    }\n    this.params = options.data;\n    this.contentLength = this.data.length;\n    this.use_ssl = this.httpOpts.use_ssl || options.use_ssl;\n    this.reqOptions = this.createHttpOptions(options);\n    this.hostname = Formatter.formatHostname(this.reqOptions.host, this.reqOptions.port, this.use_ssl);\n    this.retryAttempts = this.httpOpts.retry_attempts;\n\n    return this;\n  }\n\n  setData(options) {\n    if (!options.data) {\n      this.data = '';\n\n      return this;\n    }\n\n    this.data = Formatter.jsonStringify(options.data) || '';\n\n    return this;\n  }\n\n  setPathPrefix(options) {\n    const pathContainsPrefix = options.path && options.path.includes(this.httpOpts.default_path);\n    this.defaultPathPrefix = pathContainsPrefix ? '' : (this.httpOpts.default_path || '');\n\n    return this;\n  }\n\n  addKeepAliveOptions(reqOptions) {\n    if (this.httpOpts.keep_alive) {\n      let keepAliveMsecs = 3000;\n      let enabled = true;\n      if (Utils.isObject(this.httpOpts.keep_alive)) {\n        keepAliveMsecs = Number(this.httpOpts.keep_alive.keepAliveMsecs);\n        enabled = JSON.parse(this.httpOpts.keep_alive.enabled);\n      }\n\n      if (enabled) {\n        const port = reqOptions.port || this.httpOpts.port;\n        reqOptions.agent = HttpRequest.getAgent({\n          secure: port === 443,\n          keepAliveMsecs,\n          maxSockets: 1\n        });\n      }\n    }\n  }\n\n  createHttpOptions(options) {\n    const reqOptions = {\n      path: this.defaultPathPrefix + (options.path || ''),\n      host: options.host || this.httpOpts.host,\n      port: options.port || this.httpOpts.port,\n      method: options.method && options.method.toUpperCase() || HttpUtil.Method.GET,\n      headers: {\n        'User-Agent': HttpRequest.USER_AGENT\n      }\n    };\n\n    if (options.url) {\n      const url = new URL(options.url);\n      reqOptions.path = url.pathname;\n      reqOptions.host = url.hostname;\n\n      if (url.search && reqOptions.method === HttpUtil.Method.GET) {\n        // append search query parameters to path.\n        reqOptions.path += url.search;\n      }\n    }\n\n    this.auth = options.auth || null;\n\n    this.addKeepAliveOptions(reqOptions);\n\n    if (options.sessionId) {\n      reqOptions.path = reqOptions.path.replace(':sessionId', options.sessionId);\n    }\n\n    return reqOptions;\n  }\n\n  proxyEvents(originalIssuer, events) {\n    events.forEach(event => {\n      originalIssuer.on(event, (...args) => {\n        args.unshift(event);\n\n        if (event === 'error' && this.shouldRetryRequest()) {\n          this.isAborted = true;\n          this.socket.unref();\n          this.retryCount = this.retryCount + 1;\n          this.send();\n          this.retryAttempts = this.retryAttempts - 1;\n\n          return;\n        }\n\n        this.emit.apply(this, args);\n      });\n    });\n  }\n\n  createHttpRequest() {\n    try {\n      const req = (this.use_ssl ? https : http).request(this.reqOptions, response => {\n        this.httpResponse = new HttpResponse(response, this);\n        this.httpResponse.on('complete', this.onRequestComplete.bind(this));\n        this.proxyEvents(this.httpResponse, ['response', 'error', 'success']);\n      });\n\n      this.addAuthorizationIfNeeded(req);\n\n      return req;\n    } catch (err) {\n      err.message = `Error while trying to create HTTP request for \"${this.reqOptions.path}\": ${err.message}`;\n\n      throw err;\n    }\n  }\n\n  logRequest() {\n    const retryStr = this.retryCount ? ` (retry ${this.retryCount})` : '';\n    const params = this.params;\n    // Trim long execute script strings from params\n    if (this.reqOptions.path.includes('/execute/') && params.script) {\n      params.script = params.script.substring(0, 200) + `... (${params.script.length} characters)`;\n      params.args = params.args.map(arg => {\n        if (isString(arg) && arg.length > 200) {\n          return arg.substring(0, 200) + `... (${arg.length} characters)`;\n        }\n\n        return arg;\n      });\n    } else if (this.reqOptions.method === 'POST' && this.reqOptions.path.endsWith('/value') && params.text.startsWith(Key.NULL)) {\n      params.text = '*******';\n      params.value = '*******'.split('');\n    }\n\n    const content = `  Request ${[this.reqOptions.method, this.hostname + this.reqOptions.path, retryStr + ' '].join(' ')}`;\n\n    Logger.request(content, params);\n    Logger.info(content, params);\n\n    this.httpRequest.on('error', err => this.onRequestError(err));\n  }\n\n  logError(err) {\n    let message;\n    if (Utils.isErrorObject(err)) {\n      message = Utils.stackTraceFilter(err.stack.split('\\n'));\n    } else {\n      message = err.message || err;\n    }\n\n    Logger.error(`   ${[this.reqOptions.method, this.hostname, this.reqOptions.path].join(' ') + (err.code ? ' - ' + err.code : '')}\\n${message}`);\n  }\n\n  onRequestComplete(result, response) {\n    this.logResponse(result);\n\n    if (this.httpResponse.isRedirect) {\n      let location;\n      try {\n        // eslint-disable-next-line\n        location = require('url').parse(response.headers.location);\n      } catch (ex) {\n        Logger.error(ex);\n        this.emit('error', new Error(`Failed to parse \"Location\" header for server redirect: ${ex.message}`));\n\n        return;\n      }\n      const isAbsoluteUrl = !!location.host;\n      if (isAbsoluteUrl) {\n        this.reqOptions.host = location.hostname;\n        this.reqOptions.port = location.port;\n      }\n      this.reqOptions.path = location.pathname;\n      this.reqOptions.method = 'GET';\n\n      this.send();\n\n      return;\n    }\n\n    if (this.httpResponse.isInternalServerError && this.retryAttempts > 0) {\n      this.retryCount = this.retryCount + 1;\n      setTimeout(()=> {\n        this.retryAttempts = this.retryAttempts - 1;\n        this.send();\n      }, this.httpOpts.internal_server_error_retry_interval);\n\n      return;\n    }\n\n    if (NightwatchEventHub.runner !== 'cucumber') {\n      NightwatchEventHub.emit(LogCreated, {\n        httpOutput: Logger.collectCommandOutput()\n      });\n    }\n\n    this.emit('complete', result);\n  }\n\n  logResponse(result) {\n    let base64Data;\n    const shouldSupressData = isString(result.value) && this.addtOpts.suppressBase64Data && result.value.length > 100;\n    if (shouldSupressData) {\n      base64Data = result.value;\n      result.value = `${base64Data.substr(0, 100)}...`;\n      result.suppressBase64Data = true;\n    }\n\n    let logMethod = this.statusCode.toString().startsWith('5') ? 'error' : 'info';\n    // selenium server throws 500 errors for elements not found\n    if (this.reqOptions.path.endsWith('/element') && logMethod === 'error') {\n      const {value = ''} = result;\n      const errorMessage = Utils.isObject(value) ? value.message : value;\n      if (errorMessage.startsWith('no such element')) {\n        logMethod = 'info';\n      }\n    }\n\n    const content = `  Response ${this.statusCode} ${this.reqOptions.method} ${this.hostname + this.reqOptions.path} (${this.elapsedTime}ms)`;\n\n    Logger.response(content, result);\n    Logger[logMethod](content, result);\n\n    if (shouldSupressData) {\n      result.value = base64Data;\n    }\n  }\n\n  onRequestError(err) {\n    this.logError(err);\n\n    if (this.shouldRetryRequest(err)) {\n      this.isAborted = true;\n      this.socket.unref();\n      this.retryCount = this.retryCount + 1;\n      setTimeout(() => {\n        this.send();\n        this.retryAttempts = this.retryAttempts - 1;\n      }, 100);\n\n      return;\n    }\n\n    this.emit('error', err);\n\n  }\n\n  shouldRetryRequest(err) {\n    return this.retryAttempts > 0 && isRetryableNetworkError(err);\n  }\n\n  post() {\n    this.reqOptions.method = HttpUtil.Method.POST;\n\n    return this.send();\n  }\n\n  delete() {\n    this.reqOptions.method = HttpUtil.Method.DELETE;\n\n    return this.send();\n  }\n\n  send() {\n    this.addHeaders().setProxyIfNeeded();\n\n    this.startTime = new Date();\n    this.isAborted = false;\n\n    const {hostname, data} = this;\n    const {method, path, headers} = this.reqOptions;\n\n    this.emit('send', {\n      hostname,\n      data,\n      method,\n      path,\n      headers\n    });\n\n    this.httpRequest = this.createHttpRequest();\n    this.logRequest();\n\n    this.httpRequest.setTimeout(this.httpOpts.timeout, () => {\n      this.httpRequest.abort();\n    });\n\n    this.httpRequest.write(this.data);\n    this.httpRequest.end();\n\n    return this;\n  }\n\n  addHeaders() {\n    if (this.reqOptions.method === HttpUtil.Method.GET) {\n      this.reqOptions.headers[HttpUtil.Headers.ACCEPT] = HttpUtil.ContentTypes.JSON;\n    }\n\n    if (this.multiPartFormData) {\n      this.reqOptions.headers[HttpUtil.Headers.CONTENT_TYPE] = `${HttpUtil.ContentTypes.MULTIPART_FORM_DATA}; boundary=${this.formBoundary}`;\n    } else if (this.contentLength > 0) {\n      this.reqOptions.headers[HttpUtil.Headers.CONTENT_TYPE] = HttpUtil.ContentTypes.JSON_WITH_CHARSET;\n    }\n\n    if (HttpUtil.needsContentLengthHeader(this.reqOptions.method)) {\n      this.reqOptions.headers[HttpUtil.Headers.CONTENT_LENGTH] = this.contentLength;\n    }\n\n    return this;\n  }\n\n  setProxyIfNeeded() {\n    if (this.httpOpts.proxy !== null) {\n      try {\n        const ProxyAgent = require('proxy-agent');\n        const proxyUri = this.httpOpts.proxy;\n        this.reqOptions.agent = new ProxyAgent(proxyUri);\n      } catch (err) {\n        console.error('The proxy-agent module was not found. It can be installed from NPM with:\\n\\n' +\n          '\\tnpm install proxy-agent\\n');\n        process.exit(10);\n      }\n    }\n\n    return this;\n  }\n\n  setFormData(boundary) {\n    const crlf = '\\r\\n';\n    const delimiter = `${crlf}--${boundary}`;\n    const closeDelimiter = `${delimiter}--`;\n\n    const bufferArray = [];\n    for (const [fieldName, fieldValue] of Object.entries(this.multiPartFormData)) {\n      // set header\n      let header = `Content-Disposition: form-data; name=\"${fieldName}\"`;\n      if (fieldValue.filePath) {\n        const fileName = path.basename(fieldValue.filePath);\n        header += `; filename=\"${fileName}\"`;\n      }\n      bufferArray.push(Buffer.from(delimiter + crlf + header + crlf + crlf));\n\n      // set data\n      const {readFileSync} = require('fs');\n      if (fieldValue.filePath) {\n        bufferArray.push(readFileSync(fieldValue.filePath));\n      } else {\n        bufferArray.push(Buffer.from(fieldValue.data));\n      }\n    }\n    bufferArray.push(Buffer.from(closeDelimiter));\n\n    this.data = Buffer.concat(bufferArray);\n  }\n\n  hasCredentials() {\n    return Utils.isObject(this.httpOpts.credentials) && this.httpOpts.credentials.username;\n  }\n\n  addAuthorizationIfNeeded(req) {\n    if (this.hasCredentials() || this.auth) {\n      const auth = new Auth(req);\n\n      if (this.hasCredentials()) {\n        auth.addAuth(this.httpOpts.credentials.username, this.httpOpts.credentials.key);\n      } else if (this.auth) {\n        const {user, pass} = this.auth;\n\n        if (user && pass) {\n          auth.addAuth(user, pass);\n        }\n      }\n    }\n\n    return this;\n  }\n}\n\nfunction isRetryableNetworkError(err) {\n  if (err && err.code) {\n    return (\n      err.code === 'ECONNABORTED' ||\n      err.code === 'ECONNRESET' ||\n      err.code === 'ECONNREFUSED' ||\n      err.code === 'EADDRINUSE' ||\n      err.code === 'EPIPE' ||\n      err.code === 'ETIMEDOUT'\n    );\n  }\n\n  return false;\n}\n\nmodule.exports = HttpRequest;\n"
  },
  {
    "path": "lib/http/response.js",
    "content": "const EventEmitter = require('events');\nconst HttpUtil = require('./http.js');\nconst Formatter = require('./formatter.js');\nconst Utils = require('../utils');\n\nclass HttpResponse extends EventEmitter {\n\n  /**\n   *\n   * @param {http.ServerResponse} response\n   * @param {object} request\n   */\n  constructor(response, request) {\n    super();\n\n    this.elapsedTime = null;\n    this.res = response;\n    this.request = request;\n    this.res.setEncoding('utf8');\n    this.isRedirect = HttpUtil.isRedirect(response.statusCode);\n    this.isInternalServerError = response.statusCode >= 500;\n    this.handle();\n  }\n\n  handle() {\n    this.flushResponse();\n\n    let screenshotContent;\n\n    this.res.on('end', () => {\n      this.elapsedTime = new Date() - this.request.startTime;\n\n      if (this.flushed.length > 0) {\n        this.responseData = this.parseResponseData(this.flushed);\n\n        if (typeof this.responseData.status != 'undefined') {\n          this.responseData.status = parseInt(this.responseData.status, 10);\n        }\n      } else {\n        // for error we have to send empty response, otherwise selenium-webdriver treats the request as success.\n        this.responseData = (this.res.statusCode >= 400) ? '' : {};\n      }\n\n      this.emit('response', this.responseData);\n\n      if (this.responseData.screenshotContent) {\n        screenshotContent = this.responseData.screenshotContent;\n        delete this.responseData.screenshotContent;\n      }\n\n      this.emit('complete', this.responseData, this.res);\n\n      if (this.request.isAborted || this.isRedirect) {\n        return;\n      }\n\n      if (this.isInternalServerError && this.request.retryAttempts > 0) {\n        return;\n      }\n\n      this.emit('success', this.responseData, this.res);\n    });\n  }\n\n  flushResponse() {\n    this.flushed = '';\n    this.res.on('data', chunk => {\n      if (this.request.reqOptions.method !== 'HEAD') {\n        this.flushed += chunk;\n      }\n    });\n  }\n\n  isResponseJson() {\n    return this.res.headers['content-type'] && this.res.headers['content-type'].indexOf('application/json') > -1;\n  }\n\n  isServerError() {\n    return this.res.statusCode.toString().startsWith('5');\n  }\n\n  parseResponseData(data) {\n    let result;\n    data = data.toString();\n    data = Formatter.stripUnknownChars(data);\n\n    try {\n      result = JSON.parse(data);\n    } catch (err) {\n      result = data;\n    }\n\n    // sometimes the server non-json error responses end up parsed as strings and the error in undetected\n    if (Utils.isString(result) && this.isServerError()) {\n      return {\n        status: -1,\n        error: 'internal server error',\n        value: result\n      };\n    }\n\n    if (result.value && result.value.stacktrace) {\n      // this is in order to not pollute verbose logs\n      result.value.stacktrace = '';\n    }\n\n    return result;\n  }\n}\n\nmodule.exports = HttpResponse;\n"
  },
  {
    "path": "lib/index.js",
    "content": "const {By, Key, Capabilities} = require('selenium-webdriver');\nconst lodashMerge = require('lodash/merge');\nconst Utils = require('./utils');\nconst Settings = require('./settings/settings.js');\nconst ElementGlobal = require('./api/_loaders/element-global.js');\nconst NightwatchClient = require('./core/client.js');\nconst namespacedApi = require('./core/namespaced-api.js');\nconst {NightwatchEventHub} = require('./runner/eventHub');\nconst HttpRequest = require('./http/request.js');\nconst cdp = require('./transport/selenium-webdriver/cdp.js');\n\nconst {Logger} = Utils;\n\nconst Nightwatch = module.exports = {};\n\n/**\n * New programmatic api added in v2\n *\n * @param {Boolean} headless\n * @param {Boolean} silent\n * @param {Boolean} output\n * @param {Boolean} useAsync\n * @param {String} env\n * @param {String} browserName\n * @param {String} config\n * @param {number} timeout\n * @param {Boolean} parallel\n * @param {Object} globals\n * @param {Boolean} enable_global_apis\n * @param {Object} reporter\n *\n * @returns {{browser}}\n */\nmodule.exports.createClient = function({\n  headless = false,\n  silent = true,\n  output = true,\n  useAsync = true,\n  env = null,\n  timeout = null,\n  parallel = false,\n  reporter = null,\n  browserName = null,\n  globals = {},\n  devtools = false,\n  debug = false,\n  enable_global_apis = false,\n  config = './nightwatch.json',\n  disable_process_listener = false,\n  test_settings\n} = {}) {\n  if (browserName && !env) {\n    switch (browserName) {\n      case 'firefox':\n        env = 'firefox';\n        break;\n\n      case 'chrome':\n        env = 'chrome';\n        break;\n\n      case 'safari':\n        env = 'safari';\n        break;\n\n      case 'edge':\n      case 'MicrosoftEdge':\n        env = 'edge';\n        break;\n    }\n  }\n\n  const cliRunner = Nightwatch.CliRunner({\n    config,\n    headless,\n    env,\n    timeout,\n    devtools,\n    debug,\n    parallel,\n    disable_process_listener\n  });\n\n  const settings = arguments[0] || {};\n  const allSettings = Object.keys(settings).reduce((prev, key) => {\n    if (![\n      'headless',\n      'useAsync',\n      'env',\n      'timeout',\n      'parallel',\n      'reporter',\n      'devtools',\n      'debug',\n      'browserName',\n      'config'\n    ].includes(key)) {\n      prev[key] = settings[key];\n    }\n\n    return prev;\n  }, {});\n\n  cliRunner.setup({\n    ...allSettings,\n    silent,\n    output,\n    globals,\n    always_async_commands: useAsync\n  });\n\n  cliRunner.test_settings.disable_global_apis = cliRunner.test_settings.disable_global_apis || !enable_global_apis;\n\n  //merge settings recieved from testsuite to cli runner settings (this might have changed in hooks)\n  lodashMerge(cliRunner.test_settings, test_settings);\n\n  const client = Nightwatch.client(cliRunner.test_settings, reporter, cliRunner.argv, true);\n\n  // TODO: Do we need this (global `element` api will only be available on\n  // Nightwatch after `createClient` is called)? new `element` api is currently\n  // available on Nightwatch as named-export, but it won't be once we migrate\n  // to TypeScript, because then named-exports will be exported directly\n  // instead of first adding them to Nightwatch (default export).\n  // Some context: https://github.com/nightwatchjs/nightwatch/pull/3671\n  Object.defineProperty(Nightwatch, 'element', {\n    configurable: true,\n    value: function(locator) {\n      return ElementGlobal.element({locator, client});\n    }\n  });\n\n  const exported = {\n    updateCapabilities(value) {\n      return client.mergeCapabilities(value);\n    },\n\n    runGlobalBeforeHook() {\n      return cliRunner.globals.runGlobalHook('before', [client.settings]);\n    },\n\n    runGlobalAfterHook() {\n      return cliRunner.globals.runGlobalHook('after', [client.settings]);\n    },\n\n    launchBrowser({loadNightwatchApis = true} = {}) {\n      const {argv} = cliRunner;\n\n      return client.initialize(loadNightwatchApis)\n        .then(() => {\n          return client.createSession({argv});\n        })\n        .then((data) => {\n          if (this.settings.test_runner?.type === 'cucumber' && NightwatchEventHub.isAvailable) {\n            const NightwatchFormatter = require('./runner/test-runners/cucumber/nightwatch-format');\n\n            NightwatchFormatter.setCapabilities(data);\n          }\n\n          return client.api;\n        })\n        .catch((error) => {\n          if (this.settings.test_runner?.type === 'cucumber' && NightwatchEventHub.isAvailable) {\n            const NightwatchFormatter = require('./runner/test-runners/cucumber/nightwatch-format');\n\n            NightwatchFormatter.setCapabilities({\n              error: error\n            });\n          }\n\n          throw error;\n        });\n    },\n\n    async cleanup() {\n      await client.queue.waitForCompletion();\n      client.queue.empty();\n      client.queue.reset();\n      client.queue.removeAllListeners();\n      Logger.reset();\n    }\n  };\n\n  Object.defineProperties(exported, {\n    settings: {\n      configurable: true,\n      get: function() {\n        return client.settings;\n      }\n    },\n    transport: {\n      get: function() {\n        return client.transport;\n      }\n    },\n    nightwatch_client: {\n      configurable: true,\n      get: function() {\n        return client;\n      }\n    }\n  });\n\n  return exported;\n};\n\n/**\n * @param settings\n * @param reporter\n * @param argv\n * @returns {NightwatchClient}\n */\nNightwatch.client = function(settings, reporter = null, argv = {}, skipInit = true) {\n  const client = NightwatchClient.create(settings, argv);\n\n  if (reporter === null) {\n    const SimplifiedReporter = require('./reporter/simplified.js');\n    reporter = new SimplifiedReporter(settings);\n  }\n\n  client\n    .createTransport()\n    .setReporter(reporter);\n\n  if (skipInit) {\n    return client;\n  }\n\n  return client.initialize();\n};\n\nNightwatch.cli = function(callback) {\n  const ArgvSetup = require('./runner/cli/argv-setup.js');\n  const {argv} = ArgvSetup;\n\n  if (argv['list-files']) {\n    argv._source = argv['_'].slice(0);\n    const runner = Nightwatch.CliRunner(argv);\n\n    return runner.setupAsync()\n      .then(() => runner.getTestsFiles())\n      // eslint-disable-next-line no-console\n      .then((result) => console.log(JSON.stringify(result)));\n  }\n\n  if (argv.help) {\n    ArgvSetup.showHelp();\n  } else if (argv.info) {\n    // eslint-disable-next-line no-console\n    console.log('  Environment Info:');\n\n    require('envinfo').run(\n      {\n        System: ['OS', 'CPU'],\n        Binaries: ['Node', 'Yarn', 'npm'],\n        Browsers: ['Chrome', 'Edge', 'Firefox', 'Safari']\n      },\n      {\n        showNotFound: true,\n        duplicates: true,\n        fullTree: true\n      }// eslint-disable-next-line no-console\n    ).then(console.log);\n  } else if (argv.version) {\n    Utils.printVersionInfo();\n  } else {\n    if (!Utils.isFunction(callback)) {\n      throw new Error('Supplied callback argument needs to be a function.');\n    }\n\n    callback(argv);\n  }\n};\n\n/**\n *\n * @param [testSource]\n * @param [settings]\n */\nNightwatch.runTests = async function(testSource, settings) {\n  let argv;\n\n  if (arguments.length <= 1) {\n    settings = arguments[0] || {};\n    argv = {};\n  } else if (Array.isArray(testSource)) {\n    argv = {\n      _source: testSource\n    };\n  } else if (Utils.isObject(testSource)) {\n    argv = testSource;\n  } else if (Utils.isString(testSource)) {\n    argv = {\n      _source: [testSource]\n    };\n  }\n\n  if (argv.source) {\n    argv._source = argv.source;\n  }\n  argv.reporter = argv.reporter || Settings.DEFAULTS.default_reporter;\n\n  if (!Array.isArray(argv.reporter)) {\n    argv.reporter = [argv.reporter];\n  }\n\n  try {\n    const runner = Nightwatch.CliRunner(argv);\n\n    await runner.setupAsync(settings);\n\n    return runner.runTests();\n  } catch (err) {\n    return Promise.reject(err);\n  }\n};\n\nNightwatch.CliRunner = function(argv = {}) {\n  const CliRunner = require('./runner/cli/cli.js');\n\n  return new CliRunner(argv);\n};\n\n/**\n * @param opts\n * @return {*}\n */\nNightwatch.initClient = function(opts = {}) {\n  const cliRunner = Nightwatch.CliRunner();\n  cliRunner.initTestSettings(opts);\n\n  return Nightwatch.client(cliRunner.settings);\n};\n\n/**\n * @deprecated\n * @param argv\n * @param done\n * @param settings\n * @return {*|CliRunner}\n */\nNightwatch.runner = function(argv = {}, done = function() {}, settings = {}) {\n  if (argv.source) {\n    argv._source = argv.source;\n  }\n  argv.reporter = Settings.DEFAULTS.default_reporter;\n\n  const runner = Nightwatch.CliRunner(argv);\n\n  return runner.setup(settings)\n    .runTests()\n    .catch(err => {\n      runner.processListener.setExitCode(10);\n\n      return err;\n    })\n    .then(err => {\n      return done(err);\n    });\n};\n\nObject.defineProperty(Nightwatch, 'Logger', {\n  configurable: true,\n  get() {\n    const {logMessage, colors, underline, error, enable, disable, disableColors, isEnabled, inspectObject, request} = Logger;\n\n    return {\n      spinner(message) {\n        const ora = require('ora');\n\n        return ora(message).start();\n      },\n      log(message, ...args) {\n        logMessage('LOG', message, args, true);\n      },\n      info(message, ...args) {\n        logMessage('INFO', message, args, true);\n      },\n      warn(message, ...args) {\n        logMessage('WARN', message, args, true);\n      },\n      colors,\n      error,\n      underline,\n      enable,\n      disable,\n      disableColors,\n      isEnabled,\n      inspectObject,\n      request\n    };\n  }\n});\n\nObject.defineProperty(Nightwatch, 'by', {\n  configurable: true,\n  get() {\n    return By;\n  }\n});\n\nfunction throwIfBrowserNotAvailable() {\n  if (!global.browser) {\n    const err = new TypeError('Nightwatch client is not yet available.');\n    err.addDetailedErr = true;\n    throw err;\n  }\n}\n\nObject.defineProperty(Nightwatch, 'Key', {\n  configurable: true,\n  get() {\n    return Key;\n  }\n});\n\nObject.defineProperty(Nightwatch, 'Capabilities', {\n  configurable: true,\n  get() {\n    return Capabilities;\n  }\n});\n\n// Named exports\nconst {\n  browser, app, appium, alerts, cookies, document, window,\n  chrome, firefox, assert, verify, expect, element\n} = namespacedApi;\n\n// browser and app are overwritten below using `Object.defineProperty()`.\nmodule.exports.browser = browser;\nmodule.exports.app = app;\n\nmodule.exports.appium = appium;\nmodule.exports.alerts = alerts;\nmodule.exports.cookies = cookies;\nmodule.exports.document = document;\nmodule.exports.window = window;\n\nmodule.exports.chrome = chrome;\nmodule.exports.firefox = firefox;\n\nmodule.exports.assert = new Proxy(assert, {\n  get(_, name) {\n    return namespacedApi.assert[name];\n  }\n});\nmodule.exports.verify = new Proxy(verify, {\n  get(_, name) {\n    return namespacedApi.verify[name];\n  }\n});\nmodule.exports.expect = new Proxy(expect, {\n  apply(_, __, args) {\n    throwIfBrowserNotAvailable();\n\n    return global.browser.expect(...args);\n  },\n  get(_, name) {\n    throwIfBrowserNotAvailable();\n\n    return global.browser.expect[name];\n  }\n});\n\nmodule.exports.element = new Proxy(element, {\n  apply(_, __, args) {\n    throwIfBrowserNotAvailable();\n\n    return global.browser.element(...args);\n  },\n  get(_, name) {\n    throwIfBrowserNotAvailable();\n\n    return global.browser.element[name];\n  }\n});\n\nconst globalBrowserDescriptor = {\n  configurable: true,\n  get() {\n    throwIfBrowserNotAvailable();\n\n    return global.browser;\n  }\n};\nObject.defineProperty(Nightwatch, 'browser', globalBrowserDescriptor);\nObject.defineProperty(Nightwatch, 'app', globalBrowserDescriptor);\n\n// expose some internal modules for direct use\nmodule.exports.utils = {\n  HttpRequest,\n  cdp\n};\n"
  },
  {
    "path": "lib/page-object/base-object.js",
    "content": "const Utils = require('../utils');\nconst Section = require('./section.js');\nconst Element = require('../element');\n\nclass BaseObject {\n  static get WrappedProtocolCommands() {\n    return [\n      'elements',\n      'elementIdElement',\n      'elementIdElements'\n    ];\n  }\n\n  /**\n   * Returns the properties object passed as an argument (or null if no arguments are passed).\n   *  If the supplied properties argument is a function, it invokes that function with the page as its context.\n   *\n   * @param {Object} parent\n   * @param {Object|Function} val\n   */\n  static createProps(parent, val = {}) {\n    return Utils.isFunction(val) ? val.call(parent) : val;\n  }\n\n  /**\n   * Assigns the `elements` property for a page or section object.\n   *  For each object in the passed array, it creates a new element object by instantiating Element with its options\n   *\n   * @param {Object} parent\n   * @param {Object|Array} elements Object or array of objects to become element objects\n   */\n  static createElements(parent, elements = []) {\n    let elementObjects = {};\n\n    if (!Array.isArray(elements)) {\n      elements = [elements];\n    }\n\n    elements.forEach(els => {\n      Object.keys(els).forEach(name => {\n        let definition = Utils.isString(els[name]) ? {\n          selector: els[name]\n        } : els[name];\n\n        let options = {\n          name,\n          parent\n        };\n\n        elementObjects[name] = new Element(definition, options);\n      });\n    });\n\n    return elementObjects;\n  }\n\n  /**\n   * Assigns the `section` property for a page or section object.\n   *  For each object in the passed array, it creates a new section object by instantiating Section with its options\n   *\n   * @param {Object} parent\n   * @param {object} sections\n   */\n  static createSections(parent, sections = {}) {\n    let sectionObjects = {};\n\n    Object.keys(sections).forEach(name => {\n      let definition = sections[name];\n      let options = {\n        name,\n        parent\n      };\n\n      sectionObjects[name] = new Section(definition, options);\n    });\n\n    return sectionObjects;\n  }\n\n  /**\n   * Mixes in the passed functions to the page or section object.\n   *\n   * @param {Page|Section} parent The page object or section instance\n   * @param {Object} commands Array of commands that will be added to the page or section\n   */\n  static addCommands(parent, commands) {\n    if (Utils.isFunction(commands) || Utils.isObject(commands) && !Array.isArray(commands)) {\n      commands = [commands];\n    }\n\n    commands.forEach(m => {\n      if (Utils.isFunction(m)) {\n        BaseObject.addCommandsFromClass(parent, m);\n      } else {\n        Object.keys(m).forEach(k => {\n          try {\n            parent[k] = m[k];\n          } catch (err) {\n            const error = new Error(`Trying to overwrite page object/section \"${parent.name}\"  method/property \"${k}\".`);\n            error.detailedErr = `Using ${Object.keys(m).join(', ')}.`;\n\n            throw error;\n          }\n        });\n      }\n    });\n  }\n\n  static addCommandsFromClass(parent, CommandClass) {\n    const instance = BaseObject.createPageCommandInstance(CommandClass, parent);\n    const methodNames = Utils.getAllClassMethodNames(instance, ['httpRequest']);\n    methodNames.forEach(method => {\n      try {\n        parent[method] = function(...args) {\n          return instance[method].apply(instance, args);\n        };\n      } catch (err) {\n        const error = new Error(`Trying to overwrite page object/section \"${parent.name}\"  method/property \"${method}\".`);\n        error.detailedErr = `Using ${methodNames}.`;\n        error.displayed = false;\n\n        throw error;\n      }\n    });\n  }\n\n  static createPageCommandInstance(CommandClass, page) {\n    const {client} = page;\n\n    class CommandInstance extends CommandClass {\n      get page() {\n        return page;\n      }\n\n      get section() {\n        return this.page.section;\n      }\n\n      get api() {\n        return this.client.api;\n      }\n\n      get browser() {\n        return this.client.api;\n      }\n\n      get client() {\n        return client;\n      }\n\n      get transportActions() {\n        if (this.client && this.client.transport) {\n          return this.client && this.client.transportActions;\n        }\n\n        return {};\n      }\n\n      get driver() {\n        if (this.client && this.client.transport && this.client.transport.driver) {\n          return this.client.transport.driver;\n        }\n\n        return null;\n      }\n\n      httpRequest(requestOptions) {\n        return this.client.transport.runProtocolAction(requestOptions);\n      }\n\n      toString() {\n        return CommandClass.toString();\n      }\n    }\n\n    return new CommandInstance();\n  }\n}\n\nmodule.exports = BaseObject;\n"
  },
  {
    "path": "lib/page-object/command-wrapper.js",
    "content": "const Element = require('../element');\nconst Utils = require('../utils');\n\nconst ALLOWED_NAMESPACES = [\n  'alerts', 'cookies', 'document',\n  'assert', 'verify', 'expect'\n];\n\nfunction isAllowedNamespace(commandName) {\n  return ALLOWED_NAMESPACES.indexOf(commandName) > -1;\n}\n\nclass Command {\n  static get TYPE_ELEMENT() {\n    return 'element';\n  }\n\n  static get TYPE_SECTION() {\n    return 'section';\n  }\n\n  static isPossibleElementSelector(item, commandName = '') {\n    if (!item) {\n      return false;\n    }\n\n    if (Array.isArray(item)) {\n      return false;\n    }\n\n    if (Utils.isObject(item)) {\n      /*eslint no-prototype-builtins: 'warn'*/\n      return item.hasOwnProperty('selector') && Utils.isString(item.selector);\n    }\n\n    const Api = require('../api');\n    const ScopedElementApi = require('../api/_loaders/element-api');\n\n    return Utils.isString(item) && (item.startsWith('@') || Api.isElementCommand(commandName) || ScopedElementApi.isScopedElementCommand(commandName));\n  }\n\n  static isUserDefinedElementCommand(commandName) {\n    const ApiLoader = require('../api');\n\n    return !ApiLoader.getElementsCommandsStrict().includes(commandName);\n  }\n\n  constructor(parent, commandName, isChaiAssertion, isES6Async = false) {\n    this.parent = parent;\n    this.commandName = commandName;\n    this.isChaiAssertion = isChaiAssertion;\n    this.isES6Async = isES6Async;\n    this.isUserDefined = Command.isUserDefinedElementCommand(commandName);\n  }\n\n  /**\n   * Creates a closure that enables calling commands and assertions on the page or section.\n   * For all element commands and assertions, it fetches element's selector and locate strategy\n   *  For elements nested under sections, it sets 'recursion' as the locate strategy and passes as its first argument to the command an array of its ancestors + self\n   *  If the command or assertion is not on an element, it calls it with the untouched passed arguments\n   *\n   * @param {function} commandFn The actual command function\n   * @returns {function}\n   */\n  createWrapper(commandFn) {\n    const self = this;\n\n    return function (...args) {\n\n      if (args.length > 0 && this.__needsRecursion) {\n        // within commands\n        const inputElement = Element.createFromSelector(args[0]);\n\n        if (self.isUserDefined) {\n          inputElement.container = this.__element;\n          args[0] = inputElement;\n        } else {\n          args[0] = Element.createFromSelector({\n            locateStrategy: 'recursion',\n            selector: [this.__element, inputElement]\n          });\n        }\n      }\n\n      const client = this.client || self.parent && self.parent.client || {};\n      const result = self.executeCommand(commandFn, args, client);\n\n      if (self.isChaiAssertion) {\n        return result;\n      }\n\n      const {isES6AsyncTestcase} = client;\n\n      if ((result instanceof Promise) && (self.parent.constructor.name === 'Page' || isES6AsyncTestcase)) {\n        // when isES6AsyncTestcase is true, all page and section commands reach here (all commands\n        // return a Promise by default when isES6AsyncTestcase is true).\n        // when isES6AsyncTestcase is false, only those page commands which return promise reach here\n        // (normal API commands do not return Promise when isES6AsyncTestcase is false).\n\n        Object.assign(result, self.parent);\n\n        // Add parent prototype methods (like api, client, etc.) to result\n        const parentPrototype = Object.getPrototypeOf(self.parent);\n        Object.getOwnPropertyNames(parentPrototype).forEach((propertyName) => {\n          if (propertyName === 'constructor') {\n            return;\n          }\n          const propertyDescriptor = Object.getOwnPropertyDescriptor(parentPrototype, propertyName);\n          Object.defineProperty(result, propertyName, propertyDescriptor);\n        });\n\n        return result;\n      }\n\n      return self.parent;\n    };\n  }\n\n  validate(elementOrSection, strategy, type) {\n    let target = null;\n    let available = null;\n    let typeAvailable = 'elements';\n    let prefix;\n    let showStrategy = '';\n    let showAvailable;\n\n    switch (type) {\n      case Command.TYPE_ELEMENT:\n        target = available = this.parent.elements;\n        prefix = 'Element';\n        break;\n      case Command.TYPE_SECTION:\n        target = available = this.parent.section;\n        typeAvailable = 'sections';\n        prefix = 'Section';\n        break;\n    }\n\n    let isValid = false;\n    if (elementOrSection in target) {\n      isValid = true;\n    }\n\n    if (isValid && strategy) {\n      isValid = target[elementOrSection].locateStrategy && target[elementOrSection].locateStrategy === strategy;\n    }\n\n    if (!isValid) {\n      showAvailable = Object.keys(available);\n      if (strategy) {\n        showStrategy = `[locateStrategy='${strategy}']`;\n        showAvailable = showAvailable.map(item => `${item}[locateStrategy='${target[item].locateStrategy}']`);\n      }\n\n      throw new Error(`${prefix} \"${elementOrSection}${showStrategy}\" was not found in \"${this.parent.name}\". Available ${typeAvailable}: ${showAvailable.join(', ')}`);\n    }\n  }\n\n  /**\n   * Given an element name, returns that element object\n   *\n   * @param {string} elementName Name of element\n   * @param {string} [strategy]\n   * @returns {Element} The element object\n   */\n  getElement(elementName, strategy = null) {\n    this.validate(elementName, strategy, Command.TYPE_ELEMENT);\n\n    return this.parent.elements[elementName];\n  }\n\n  /**\n   * Given a section name, returns that section object\n   *\n   * @param {string} sectionName Name of section\n   * @param {string} [strategy]\n   * @returns {Element} The section object\n   */\n  getSection(sectionName, strategy = null) {\n    this.validate(sectionName, strategy, Command.TYPE_SECTION);\n\n    return this.parent.section[sectionName];\n  }\n\n  getSelectorFromArgs(args) {\n    let selectorArg = args[0];\n\n    const isSelector = Command.isPossibleElementSelector(selectorArg, this.commandName);\n    if (isSelector) {\n      // check if both strategy and selector are specified as args\n      const {LocateStrategy} = Utils;\n      const isStrategySpecified = LocateStrategy.isValid(selectorArg);\n      if (isStrategySpecified && Utils.isString(args[1])) {\n        selectorArg = {\n          selector: args[1],\n          locateStrategy: args[0]\n        };\n      }\n\n      return selectorArg;\n    }\n\n    return null;\n  }\n\n  /**\n   * Identifies element references (@-prefixed selectors) within an argument\n   * list and converts it into an element object with the appropriate\n   * selector or recursion chain of selectors.\n   *\n   * @param {Array} args The argument list to check for an element selector.\n   */\n  parseElementSelector(args) {\n    const selector = this.getSelectorFromArgs(args);\n\n    if (!selector) {\n      return;\n    }\n\n    // currently only support first argument for @-elements\n    let inputElement = Element.createFromSelector(selector);\n\n    if (inputElement.hasElementSelector()) {\n      const nameSections = inputElement.selector.substring(1).split(':');\n      const name = nameSections[0];\n      const pseudoSelector = nameSections[1] || null;\n\n      // When true, indicates that the selector references a selector within a section rather than an elements definition.\n      // eg: .expect.section('@footer').to.be.visible\n      const isSectionSelector = this.isChaiAssertion && this.commandName === 'section';\n\n      const getter = isSectionSelector ? this.getSection : this.getElement;\n\n      const strategy = Utils.isObject(selector) && selector.locateStrategy || null;\n      const elementOrSection = getter.call(this, name, strategy);\n      elementOrSection.pseudoSelector = pseudoSelector;\n\n      Element.copyDefaults(inputElement, elementOrSection);\n      inputElement.locateStrategy = elementOrSection.locateStrategy;\n      inputElement.selector = elementOrSection.selector; // force replacement of @-selector\n      inputElement = inputElement.getRecursiveLookupElement() || inputElement;\n      args[0] = inputElement;\n    } else {\n      // if we're calling an element on a section using a css/xpath selector,\n      //  then we need to retrieve the element using recursion\n      const Section = require('./section.js');\n      if (this.parent instanceof Section) {\n        inputElement.parent = this.parent;\n        inputElement = inputElement.getRecursiveLookupElement() || Element.createFromSelector({\n          locateStrategy: 'recursion',\n          selector: [this.parent, inputElement]\n        });\n\n        const ScopedElementApi = require('../api/_loaders/element-api');\n        if (ScopedElementApi.isScopedElementCommand(this.commandName)) {\n          // only locate the parent sections recursively and then find the main element using\n          // original method and arguments.\n          this.onlyLocateSectionsRecursively = true;\n        }\n\n        args[0] = inputElement;\n      }\n    }\n  }\n\n  /**\n   * @param {Function} commandFn\n   * @param {Array} args\n   * @param {Object} context\n   */\n  executeCommand(commandFn, args, context) {\n    let parseArgs;\n    if (Utils.isObject(args[0]) && Array.isArray(args[0].args)) {\n      parseArgs = args[0].args;\n    } else {\n      parseArgs = args;\n    }\n\n    this.parseElementSelector(parseArgs);\n\n    return commandFn.apply(context, args);\n  }\n}\n\nclass CommandLoader {\n\n  /**\n   * Entry point to add commands (elements commands, assertions, etc) to the page or section\n   *\n   * @param {Object} parent The parent page or section\n   * @param {function} commandLoader function that retrieves commands\n   * @returns {null}\n   */\n  static addWrappedCommands(parent, commandLoader) {\n    const commands = {\n      get '__pageObjectItem__' () {\n        return parent;\n      }\n    };\n\n    const wrappedCommands = commandLoader(commands);\n\n    CommandLoader.applyCommandsToTarget(parent, parent, wrappedCommands);\n    if (parent.assert && parent.verify) {\n      const ApiLoader = require('../api');\n      parent.assert = ApiLoader.makeAssertProxy(parent.assert);\n      parent.verify = ApiLoader.makeAssertProxy(parent.verify);\n    }\n  }\n\n  static addWrappedCommandsAsync(parent, commandLoader) {\n    const commands = {};\n\n    const wrappedCommands = commandLoader(commands);\n    CommandLoader.applyCommandsToTarget(parent, parent, wrappedCommands);\n\n    return wrappedCommands;\n  }\n\n  /**\n   * Adds commands (elements commands, assertions, etc) to the page or section\n   *\n   * @param {Object} parent The parent page or section\n   * @param {Object} target What the command is added to (parent|section or assertion object on parent|section)\n   * @param {Object} commands\n   * @returns {null}\n   */\n  static applyCommandsToTarget(parent, target, commands) {\n    Object.keys(commands).forEach(function(commandName) {\n      if (isAllowedNamespace(commandName)) {\n        target[commandName] = target[commandName] || {};\n\n        const isChaiAssertion = commandName === 'expect';\n        const namespace = commands[commandName];\n\n        Object.keys(namespace).forEach(function(nsCommandName) {\n          target[commandName][nsCommandName] = CommandLoader.addCommand({\n            target: target[commandName],\n            commandFn: namespace[nsCommandName],\n            commandName: nsCommandName,\n            parent,\n            isChaiAssertion\n          });\n        });\n      } else {\n        // don't load namespaces here, otherwise they'll be wrapped by a function.\n        if (Utils.isObject(commands[commandName])) {\n          return;\n        }\n\n        target[commandName] = CommandLoader.addCommand({\n          target,\n          commandFn: commands[commandName],\n          commandName,\n          parent,\n          isChaiAssertion: false,\n          isES6Async: Utils.isES6AsyncFn(commands[commandName])\n        });\n      }\n    });\n  }\n\n  /**\n   * @param parent\n   * @param originalApi\n   * @param targetApi\n   * @param {string} commandName\n   * @returns {function}\n   */\n  static wrapElementCommand(parent, originalApi, targetApi, commandName) {\n    const originalFn = originalApi[commandName];\n\n    const command = new Command(parent, commandName, false);\n\n    return function(...args) {\n      const origArgs = args.slice();\n\n      command.parseElementSelector(args);\n\n      if (command.onlyLocateSectionsRecursively) {\n        // only happens in case of new scoped element api, when non @-referenced selector is passed\n        // to element api methods for sections. Doing this is not really necessary for `find` and `findAll`\n        // methods but only for testing-library methods (which only accepts string as first argument),\n        // but we do it for them anyways.\n\n        // transfer n-1 selectors to `element()` and the main selector (origArgs) to the actual method.\n        args[0].selector.pop();\n\n        const parentSectionElement = targetApi(args[0]);\n\n        return parentSectionElement[commandName](...origArgs);\n      }\n\n      return originalFn.apply(targetApi, args);\n    };\n  }\n\n  /**\n   * @param parent\n   * @param api\n   * @param {Array} commands\n   */\n  static wrapProtocolCommands(parent, api, commands) {\n    commands.forEach(commandName => {\n      api[commandName] = CommandLoader.wrapElementCommand(parent, api, api, commandName);\n    });\n  }\n\n  static wrapScopedElementApi(parent, api, elementCommands) {\n    const wrappedElementFn = CommandLoader.wrapElementCommand(parent, api, api, 'element');\n\n    elementCommands.forEach(commandName => {\n      let names = commandName;\n      if (!Array.isArray(names)) {\n        names = [names];\n      }\n\n      names.forEach(commandName => {\n        wrappedElementFn[commandName] = CommandLoader.wrapElementCommand(parent, api.element, wrappedElementFn, commandName);\n      });\n    });\n\n    api.element = wrappedElementFn;\n  }\n\n  static addCommand({target, commandFn, commandName, parent, isChaiAssertion, isES6Async = false, overwrite = false}) {\n    if (target[commandName] && !overwrite) {\n      const err = new TypeError(`Error while loading the page object commands: the command \"${commandName}\" is already defined.`);\n      err.displayed = false;\n      err.showTrace = false;\n\n      throw err;\n    }\n\n    const command = new Command(parent, commandName, isChaiAssertion, isES6Async);\n\n    return command.createWrapper(commandFn);\n  }\n}\n\nmodule.exports = CommandLoader;\n"
  },
  {
    "path": "lib/page-object/index.js",
    "content": "const Utils = require('../utils');\nconst CommandWrapper = require('./command-wrapper.js');\nconst BaseObject = require('./base-object.js');\nconst ScopedElementAPILoader = require('../api/_loaders/element-api');\n\nconst shouldReturnPromise = function() {\n  return this.client.isES6AsyncTestcase || this.client.isES6AsyncCommand;\n};\n\nconst validateUrl = function(url) {\n  let goToUrl = this.getUrl(url);\n\n  if (!goToUrl) {\n    goToUrl = this.client.settings.launchUrl;\n  } else if (Utils.isString(goToUrl) && Utils.relativeUrl(goToUrl)) {\n    if (!this.client.settings.launchUrl) {\n      const err = new Error(`Invalid URL ${goToUrl} in \"${this.name}\" page object. When using relative uris, you must ` +\n        'define a \"baseUrl\" in your nightwatch config.');\n\n      throw err;\n    }\n\n    goToUrl = Utils.uriJoin(this.client.settings.launchUrl, goToUrl);\n  }\n\n  if (goToUrl === null) {\n    const err = new Error(`Invalid URL: You must either add a url property to the \"${this.name}\" or provide a url as an argument`);\n\n    throw err;\n  }\n\n  return goToUrl;\n};\n\n/**\n * Class that all pages subclass from\n *\n * @param {Object} options Page options defined in page object\n * @constructor\n */\nclass Page extends BaseObject {\n  constructor(options, commandLoader, client) {\n    super();\n\n    this.commandLoader = commandLoader;\n\n    this.__options = options;\n    this.__client = client;\n    this.__api = Object.assign({}, client.api);\n    this.__props = Page.createProps(this, options.props);\n    this.__elements = Page.createElements(this, options.elements);\n    this.__sections = Page.createSections(this, options.sections);\n\n    const pageCommands = options.commands || [];\n    Page.addCommands(this, pageCommands);\n\n    CommandWrapper.addWrappedCommands(this, this.commandLoader);\n    CommandWrapper.wrapProtocolCommands(this, this.api, BaseObject.WrappedProtocolCommands);\n    CommandWrapper.wrapScopedElementApi(this, this.api, ScopedElementAPILoader.availableElementCommands);\n\n    Object.defineProperty(this, 'element', {\n      get() {\n        return this.api.element;\n      },\n      enumerable: true,\n      configurable: false\n    });\n  }\n\n  get api() {\n    return this.__api;\n  }\n\n  get client() {\n    return this.__client;\n  }\n\n  get name() {\n    return this.__options.name;\n  }\n\n  /**\n   * @return {object}\n   */\n  get props() {\n    return this.__props;\n  }\n\n  /**\n   * @return {object}\n   */\n  get elements() {\n    return this.__elements;\n  }\n\n  /**\n   * @return {object}\n   */\n  get section() {\n    return this.__sections;\n  }\n\n  get url() {\n    return this.__options.url;\n  }\n\n  set url(val) {\n    this.__options.url = val;\n  }\n\n  /**\n   * Returns the url passed as an argument (or null if no arguments are passed).\n   *  If the supplied url is a function, it invokes that function with the page as its context.\n   *\n   * @method getUrl\n   * @param {function|string|object} url\n   * @return {function}\n   */\n  get getUrl() {\n    /**\n     * @returns {string|null}\n     */\n    return (url) => {\n      if (Utils.isFunction(url)) {\n        return url.call(this);\n      }\n\n      if (Utils.isString(url)) {\n        return url;\n      }\n\n      if (Utils.isObject(url) && this.url) {\n        return Utils.replaceParams(this.url, url);\n      }\n\n      return null;\n    };\n  }\n\n\n\n  /**\n   * This command is an alias to url and also a convenience method because when called without any arguments\n   *  it performs a call to .url() with passing the value of `url` property on the page object.\n   * Uses `url` protocol command.\n   *\n   * @method navigate\n   * @param {Object} [url=this.url] Url to navigate to.\n   * @param {function} [callback] Optional callback function to be called when the command finishes.\n   * @returns {*}\n   */\n  get navigate() {\n    return function(url, callback) {\n      let goToUrl;\n\n      if (typeof url == 'function' && !callback) {\n        callback = url;\n        url = this.url;\n      }\n\n      if (!url) {\n        url = this.url;\n      }\n\n      if (!shouldReturnPromise.call(this)) {\n        goToUrl = validateUrl.call(this, url, callback);\n        this.api.url(goToUrl, callback);\n\n        return this;\n      }\n\n      const promise = new Promise((resolve, reject) => {\n        (async () => {\n          let goToUrl;\n\n          try {\n            goToUrl = validateUrl.call(this, url, callback);\n          } catch (err) {\n            reject(err);\n\n            return;\n          }\n\n          await this.api.url(goToUrl, callback);\n\n          resolve();\n        })();\n      });\n\n      Object.assign(promise, this);\n\n      return promise;\n    };\n  }\n}\n\nmodule.exports = Page;\n"
  },
  {
    "path": "lib/page-object/section.js",
    "content": "const Element = require('../element');\nconst CommandWrapper = require('./command-wrapper.js');\nconst ScopedElementAPILoader = require('../api/_loaders/element-api');\n\n/**\n * Class that all sections subclass from\n *\n * @param {Object} definition User-defined section options defined in page object\n * @param {Object} options Additional options to be given to the section.\n * @constructor\n */\nclass Section extends Element {\n  get section() {\n    return this.sections;\n  }\n\n  /**\n   * A shallow copy of the page-object api is sufficient because the wrapping of api commands (e.g. .elements()) is only one-level\n   */\n  createApiShallowCopy() {\n    return Object.assign({}, this.parent.api);\n  }\n\n\n  constructor(definition, options) {\n    super(definition, options);\n\n    this.client = this.parent.client;\n    this.api = this.createApiShallowCopy();\n    this.commandLoader = this.parent.commandLoader;\n\n    const BaseObject = require('./base-object.js');\n    this.props = BaseObject.createProps(this, definition.props);\n    this.elements = BaseObject.createElements(this, definition.elements);\n    this.sections = BaseObject.createSections(this, definition.sections);\n\n    BaseObject.addCommands(this, definition.commands || []);\n\n    CommandWrapper.addWrappedCommands(this, this.commandLoader);\n    CommandWrapper.wrapProtocolCommands(this, this.api, BaseObject.WrappedProtocolCommands);\n    CommandWrapper.wrapScopedElementApi(this, this.api, ScopedElementAPILoader.availableElementCommands);\n\n    Object.defineProperty(this, 'element', {\n      get() {\n        return this.api.element;\n      },\n      enumerable: true,\n      configurable: false\n    });\n  }\n}\n\n\nmodule.exports = Section;\n"
  },
  {
    "path": "lib/reporter/axe-report.js",
    "content": "const CliTable = require('cli-table3');\n\nconst Utils = require('../utils');\nconst {Logger} = Utils;\n\n\nconst describeViolations = (violations) => {\n  const aggregate = {};\n\n  violations.map(({nodes}, index) => {\n    nodes.forEach(({target, html}) => {\n      const key = JSON.stringify(target) + html;\n\n      if (aggregate[key]) {\n        aggregate[key].violations = aggregate[key].violations || [];\n        aggregate[key].violations.push(index);\n      } else {\n        aggregate[key] = {\n          target: JSON.stringify(target),\n          html,\n          index: [index]\n        };\n      }\n    });\n  });\n\n  return Object.values(aggregate).map(({target, html, violations}) => {\n    return {target, html, violations: JSON.stringify(violations)};\n  });\n};\n\nconst describePasses = (passes) => {\n  const aggregate = {};\n\n  passes.map(({nodes}, index) => {\n    nodes.forEach(({target, html}) => {\n      const key = JSON.stringify(target) + html;\n      aggregate[key] = {\n        target: JSON.stringify(target),\n        html\n      };\n\n    });\n  });\n\n  return Object.values(aggregate).map(({target, html}) => {\n    return {target, html};\n  });\n};\n\n\nmodule.exports = class AxeReport {\n\n  static createTable() {\n    const table = new CliTable({\n      chars: {\n        'mid': '', 'left-mid': '', 'mid-mid': '', 'right-mid': '',\n        'bottom': '═', 'bottom-mid': '', 'bottom-left': '╚', 'bottom-right': '╝'\n      }\n    });\n    table.push(\n      [\n        Logger.colors.light_cyan('ID'),\n        Logger.colors.light_cyan('Impact'),\n        Logger.colors.light_cyan('Description'),\n        Logger.colors.light_cyan('Nodes')\n      ],\n      [\n        Logger.colors.stack_trace('─────────────────────'),\n        Logger.colors.stack_trace('──────────'), '',\n        Logger.colors.stack_trace('──────────')\n      ]\n    );\n\n    return table;\n  }\n\n  constructor(report, {detailedReport = true, includeHtml = true} = {}) {\n    this.report = report;\n    this.detailedReport = detailedReport;\n    this.includeHtml = includeHtml;\n  }\n\n  hasViolations() {\n    return this.report.violations.length > 0;\n  }\n\n  printPasses() {\n    const table = new CliTable({\n      chars: {\n        'mid': '', 'left-mid': '', 'mid-mid': '', 'right-mid': '',\n        'bottom': '═', 'bottom-mid': '', 'bottom-left': '╚', 'bottom-right': '═╝'\n      }\n    });\n    table.push(\n      [\n        Logger.colors.light_cyan('Rule'),\n        Logger.colors.light_cyan('Description'),\n        Logger.colors.light_cyan('Nodes')\n      ],\n      [\n        Logger.colors.stack_trace('─────────────────────'),\n        Logger.colors.stack_trace('──────────'),\n        Logger.colors.stack_trace('───────')\n      ]\n    );\n\n\n    const {passes} = this.report;\n    passes.forEach(({id, description, nodes}) => {\n      table.push([id, description, nodes.length]);\n    });\n\n    const nodes = describePasses(passes).map(({target, html}) => {\n      return {target, html};\n    });\n\n    table.push(\n      [\n        Logger.colors.stack_trace('─────────────────────'),\n        Logger.colors.stack_trace('────────────────────────'),\n        Logger.colors.stack_trace('───────')\n      ],\n      [\n        Logger.colors.light_cyan('Target'),\n        {colSpan: 2, content: Logger.colors.light_cyan('Html')}\n      ]\n    );\n\n    nodes.forEach(({target, html}) => {\n      table.push(\n        [\n          target,\n          {colSpan: 2, content: Logger.colors.stack_trace(html)}\n        ]\n      );\n    });\n\n    // eslint-disable-next-line no-console\n    console.log(table.toString());\n  }\n\n  printViolations(component) {\n    // eslint-disable-next-line no-console\n    console.log('\\n' + Logger.colors.light_red(`Accessibility violations for: ${component}`));\n    const {violations} = this.report;\n\n    const table = AxeReport.createTable();\n\n    violations.forEach(({id, impact, description, nodes}) => {\n      table.push([id, impact, description, nodes.length]);\n    });\n\n    // summary\n    if (this.detailedReport) {\n      const nodeViolations = describeViolations(violations).map(({target, html, violations}) => {\n        if (!this.includeHtml) {\n          return {\n            target,\n            violations\n          };\n        }\n\n        return {target, html, violations};\n      });\n\n      table.push(\n        [\n          Logger.colors.stack_trace('─────────────────────'),\n          Logger.colors.stack_trace('──────────'), '',\n          Logger.colors.stack_trace('──────────')\n        ],\n        [{colSpan: 2, content: Logger.colors.light_cyan('Target')}, Logger.colors.light_cyan('Html'), Logger.colors.light_cyan('Violations')]\n      );\n\n      nodeViolations.forEach(({target, html, violations}) => {\n        table.push(\n          [{colSpan: 2, content: target}, Logger.colors.stack_trace(html), violations]\n        );\n      });\n      table.push([\n        {colSpan: 4, content: ''}\n      ]);\n    }\n    // eslint-disable-next-line no-console\n    console.log(table.toString());\n  }\n};\n"
  },
  {
    "path": "lib/reporter/base-reporter.js",
    "content": "const fs = require('fs');\nconst stripAnsi = require('strip-ansi');\nconst Utils = require('../utils');\nconst Results = require('./results.js');\n\nmodule.exports = class BaseReporter {\n  constructor(results, opts = {}) {\n    this.results = results;\n    this.options = opts;\n  }\n\n  adaptAssertions(module) {\n    module.completed = Object.keys(module.completed).reduce(function(prev, item) {\n      if ((module.skipped && module.skipped.includes(item))) {\n        return prev;\n      }\n\n      const testcase = module.completed[item];\n      const assertions = testcase.assertions;\n\n      for (let i = 0; i < assertions.length; i++) {\n        assertions[i].message = stripAnsi(assertions[i].message);\n\n        if (assertions[i].stackTrace) {\n          assertions[i].stackTrace = stripAnsi(assertions[i].stackTrace);\n          assertions[i].stackTrace = Utils.stackTraceFilter(assertions[i].stackTrace.split('\\n'));\n        }\n      }\n\n      if (testcase.failed > 0 && assertions.length === 0 && testcase.lastError) {\n        const stackParts = testcase.stackTrace.split('\\n');\n        testcase.stackTrace = Utils.stackTraceFilter(stackParts);\n        testcase.message = stripAnsi(testcase.lastError.message);\n      }\n\n      prev[item] = testcase;\n\n      return prev;\n    }, {});\n\n    module.completedSections = Object.keys(module.completedSections).reduce(function(prev, item) {\n      if ((module.skippedAtRuntime && module.skippedAtRuntime.includes(item)) ||\n          (module.skippedByUser && module.skippedByUser.includes(item))\n      ) {\n        return prev;\n      }\n\n      const testcase = module.completedSections[item];\n      const commands = testcase.commands;\n\n      for (let i = 0; i < commands.length; i++) {\n        if (commands[i].status === Results.TEST_FAIL && commands[i].result.stack) {\n          commands[i].result.message = stripAnsi(commands[i].result.message || '');\n          if (commands[i].result.stack) {\n            commands[i].result.stack = stripAnsi(commands[i].result.stack);\n            commands[i].result.beautifiedStack = Utils.beautifyStackTrace(commands[i].result.stack, true, module.modulePath, false);\n          }\n        }\n      }\n\n      prev[item] = testcase;\n\n      return prev;\n    }, {});\n  }\n\n  writeReportFile(filename, rendered, shouldCreateFolder, output_folder) {\n    return (shouldCreateFolder ? Utils.createFolder(output_folder) : Promise.resolve())\n      .then(() => {\n        return new Promise((resolve, reject) => {\n          fs.writeFile(filename, rendered, function(err) {\n            if (err) {\n              return reject(err);\n            }\n\n            resolve();\n          });\n        });\n      });\n  }\n\n  /**\n   * @override\n   */\n  async writeReport(moduleKey) {}\n\n  write() {\n    const keys = Object.keys(this.results.modules);\n    const promises = keys.map(moduleKey => {\n      return this.writeReport(moduleKey);\n    });\n\n    return Promise.all(promises);\n  }\n};\n"
  },
  {
    "path": "lib/reporter/global-reporter.js",
    "content": "const path = require('path');\nconst Convert = require('ansi-to-html');\nconst stripAnsi = require('strip-ansi');\n\nconst Concurrency = require('../runner/concurrency');\nconst DefaultSettings = require('../settings/defaults.js');\nconst Utils = require('../utils');\nconst {Logger, isFunction} = Utils;\nconst Results = require('./results.js');\nconst AxeReport = require('./axe-report.js');\nconst Summary = require('./summary.js');\nconst PluginLoader = require('../api/_loaders/plugin.js');\n\nconst colors = Logger.colors;\n\nmodule.exports = class GlobalReporter {\n  static get initialReport() {\n    return {\n      passed: 0,\n      failed: 0,\n      errors: 0,\n      skipped: 0,\n      tests: 0,\n      assertions: 0,\n      errmessages: [],\n      errorsPerTest: {},\n      modules: {},\n      modulesWithEnv: {},\n      elapsedTime: 0,\n      startTimestamp: null,\n      endTimestamp: null\n    };\n  }\n\n  constructor(reporter = DefaultSettings.default_reporter, settings, {openReport = false, reportFileName = null} = {}) {\n    this.suiteResults = [];\n    this.skippedSuites = 0;\n    this.uncaughtErr = null;\n    this.reportFileName = reportFileName;\n\n    this.reporterFile = [];\n    if (Array.isArray(reporter)) {\n      // Any subsequent changes in `this.reporterFile` shouldn't lead to changes in\n      // `argv.reporter` provided by the user, or `DefaultSettings.default_reporter`.\n      this.reporterFile = reporter.slice(0);\n    } else if (typeof reporter == 'string') {\n      this.reporterFile = reporter.split(',');\n    }\n    this.settings = settings;\n    this.summary = new Summary(settings);\n    this.openReport = openReport;\n    this.ansiConverter = new Convert();\n  }\n\n  registerUncaughtErr(err) {\n    this.uncaughtErr = err;\n  }\n\n  isDisabled() {\n    return this.settings.output_folder === false;\n  }\n\n  hasTestFailures() {\n    return this.uncaughtErr || this.suiteResults.some(item => {\n      return item.hasFailures;\n    });\n  }\n\n  addTestSuiteResults(testResults, httpOutput) {\n    testResults = testResults || {};\n    const loggerOutput = httpOutput || Logger.collectOutput();\n    testResults.httpOutput = loggerOutput.map(item => {\n      return [item[0], this.ansiConverter.toHtml(item[1]),\n        (item[2] ? this.ansiConverter.toHtml(item[2]) : '')];\n    });\n\n    testResults.rawHttpOutput = loggerOutput.map(item => {\n      return [item[0], stripAnsi(item[1] || '').replace(/&#39;/g, '\\''),\n        (item[2] ? stripAnsi(item[2]) : '').replace(/&#39;/g, '\\'')];\n    });\n    this.suiteResults.push(testResults);\n\n    return this;\n  }\n\n  setupChildProcessListener(emitter) {\n    if (!Concurrency.isTestWorker()) {\n      emitter.on('message', data => {\n        data = this.settings.use_child_process ? JSON.parse(data) : data;\n        this.addTestSuiteResults(data.results, data.httpOutput);\n      });\n    }\n  }\n\n  create(startTime) {\n    const initialReport = GlobalReporter.initialReport;\n\n    if (this.uncaughtErr) {\n      initialReport.errors++;\n      const errorMessage = Logger.getErrorContent(this.uncaughtErr);\n      initialReport.errmessages.push(errorMessage);\n    }\n\n    const endTime = new Date().getTime();\n    this.elapsedTime = endTime - startTime;\n\n    this.globalResults = Results.createGlobalReport(this.suiteResults, initialReport);\n    this.globalResults.elapsedTime = (this.elapsedTime / 1000).toPrecision(4);\n    this.globalResults.startTimestamp = new Date(startTime).toUTCString();\n    this.globalResults.endTimestamp = new Date(endTime).toUTCString();\n\n    return this;\n  }\n\n  print() {\n    if (Concurrency.isWorker() || !this.settings.output) {\n      return this;\n    }\n\n    if (this.hasTestFailures()) {\n      const countMessage = this.getTestsFailedMessage();\n\n      const {columns = 100} = process.stdout;\n      // eslint-disable-next-line no-console\n      console.log(colors.light_red('\\n' + new Array(Math.max(100, columns - 20)).join('─')));\n\n      // eslint-disable-next-line no-console\n      console.log(`\\n  ️${colors.light_red('TEST FAILURE')} ${colors.stack_trace('(' + Utils.formatElapsedTime(this.elapsedTime) + ')')}${colors.light_red(':')} ${countMessage}\\n`);\n\n      this.summary.print(this.globalResults);\n      // eslint-disable-next-line no-console\n      console.log('');\n    } else {\n      if (!this.shouldShowSummary()) {\n        return;\n      }\n\n      const message = this.getTestsPassedMessage();\n      // eslint-disable-next-line no-console\n      console.log(`\\n${message} ${colors.stack_trace('(' + Utils.formatElapsedTime(this.elapsedTime) + ')')}`);\n    }\n\n    this.printA11yReport();\n\n    return this;\n  }\n\n  loadReporter() {\n    const allAvailableReporters = this.reporterFile.slice(0);\n\n    return Promise.all(allAvailableReporters.map((reporter) => this.loadFile(reporter)));\n  }\n\n  printA11yReport() {\n    Object.keys(this.globalResults.modules).forEach(testSuite => {\n      Object.keys(this.globalResults.modules[testSuite].completed).forEach(key => {\n        const testcase = this.globalResults.modules[testSuite].completed[key];\n\n        if (testcase.a11y) {\n          const a11yReport = new AxeReport(testcase.a11y);\n\n          if (testcase.a11y.verbose || a11yReport.hasViolations()) {\n            // eslint-disable-next-line no-console\n            console.log('\\n' + Logger.colors.green(`Accessibility report for: ${testcase.a11y.component}`));\n          }\n\n          if (testcase.a11y.verbose) {\n            a11yReport.printPasses(key);\n          }\n\n          if (a11yReport.hasViolations()) {\n            a11yReport.printViolations(testcase.a11y.component);\n          }\n        }\n      });\n    });\n  }\n\n  async loadFile(reporterFile) {\n    const builtInReporterFileName = path.join(__dirname, 'reporters', reporterFile + '.js');\n    const fileExists = await Utils.fileExists(builtInReporterFileName);\n\n    if (!fileExists) {\n      return this.loadCustomReporter(reporterFile);\n    }\n\n    return require(builtInReporterFileName);\n  }\n\n  async loadCustomReporter(reporterFile) {\n    let customReporterModuleExists;\n    let reporter;\n\n    try {\n      reporter = require(reporterFile);\n      customReporterModuleExists = true;\n    } catch (err) {\n      customReporterModuleExists = false;\n    }\n\n    const customReporterExists = await Utils.fileExists(reporterFile);\n\n    if (!customReporterExists && !customReporterModuleExists) {\n      throw new Error(`The custom reporter \"${reporterFile}\" cannot be resolved.`);\n    }\n\n    if (!customReporterModuleExists) {\n      reporter = require(path.resolve(reporterFile));\n    }\n\n    if (Utils.isFunction(reporter.write)) {\n      return reporter;\n    }\n\n    throw new Error(`The custom reporter \"${reporterFile}\" must have a public \".write(results, options, [callback])\" method defined which should return a Promise.`);\n  }\n\n  async writeReportToFile(globalResults) {\n    if (this.isDisabled()) {\n      return;\n    }\n\n    try {\n      await Utils.createFolder(this.settings.output_folder);\n      const reporters = await this.loadReporter();\n\n      return Promise.all(\n        reporters.map(reporterFile => this.writeReport(reporterFile, globalResults))\n      );\n    } catch (err) {\n      const error = new Error('An error occurred while trying to save the report file');\n      error.detailedErr = err.message;\n\n      throw error;\n    }\n  }\n\n  async writeReport(reporter, globalResults) {\n    const {globals, output_folder, start_session, folder_format, reporter_options: {filename_format}} = this.settings;\n    const needsCallback = reporter.write.length === 3;\n    const options = {\n      filename_prefix: this.settings.report_prefix,\n      report_filename: this.reportFileName,\n      output_folder,\n      globals,\n      start_session,\n      reporter,\n      openReport: this.openReport,\n      filename_format,\n      folder_format\n    };\n\n    if (needsCallback) {\n      // backwards compatibility\n      return new Promise((resolve, reject) => {\n        reporter.write(globalResults, options, function (err) {\n          if (err) {\n            return reject(err);\n          }\n          resolve();\n        });\n      });\n    }\n\n    return await reporter.write(globalResults, options);\n  }\n\n  shouldShowSummary() {\n    const modules = Object.keys(this.globalResults.modules);\n    if (modules.length > 1) {\n      return true;\n    }\n\n    if (modules.length <= 0) {\n      return false;\n    }\n\n    return Object.keys(this.globalResults.modules[modules[0]].completed).length > 1;\n  }\n\n  hasAssertionCount() {\n    const testsCounts = this.getTotalTestsCount();\n\n    return !this.settings.unit_tests_mode && testsCounts > 0 && this.globalResults.assertions > 0;\n  }\n\n  getTotalTestsCount() {\n    return Object.keys(this.globalResults.modules)\n      .reduce((count, moduleKey) => {\n        const module = this.globalResults.modules[moduleKey];\n\n        return count + module.tests;\n      }, 0);\n  }\n\n  getTestsFailedMessage() {\n    const hasCount = this.hasAssertionCount();\n    const totalTests = this.getTotalTestsCount();\n\n    let errorsMsg = '';\n    const failedMsg = hasCount ? 'assertions' : 'tests';\n    let passedMsg = colors.green(this.globalResults.passed) + ' passed'; // assertions passed\n\n    const skippedSuitesCount = this.skippedSuites > 0 ? `\\n   - ${colors.light_red(this.skippedSuites)} other test suites were aborted; ` : '';\n\n    if (!hasCount) {\n      const passedCount = Math.max(0, totalTests - this.globalResults.failed - this.globalResults.errors); // testcases passed\n      passedMsg = '\\n   - ' + colors.green(passedCount + '/' + (totalTests > 0 ? totalTests : 'NA')) + ' tests passed';\n    }\n\n    let skipped = '';\n    if (this.globalResults.skipped) {\n      skipped = `\\n   - ${colors.cyan(this.globalResults.skipped)} skipped`;\n    }\n\n    const globalErrors = this.globalResults.errors;\n    if (globalErrors) {\n      const suffix = globalErrors > 1 ? 's' : '';\n      errorsMsg += `\\n   - ${colors.red(globalErrors)} error${suffix} during execution;`;\n    }\n\n    const failedCountMsg = `\\n   - ${colors.red(this.globalResults.failed)} ${failedMsg} failed;`;\n\n    return `${errorsMsg} ${skippedSuitesCount}${failedCountMsg} ${passedMsg}${skipped}`;\n  }\n\n  getTestsPassedMessage() {\n    const hasCount = this.hasAssertionCount();\n    let message;\n    let count;\n\n    if (hasCount) {\n      count = this.globalResults.passed;\n      message = colors.green(`  ✨ PASSED. ${count} ${count > 1 ? 'total assertions' : ' assertion'}`);\n    } else {\n      count = this.getTotalTestsCount();\n      message = `${colors.green('  ✨ PASSED. ' + count)} tests`;\n    }\n\n    return message;\n  }\n\n  getPluginReporters() {\n    const plugins = this.settings.plugins || [];\n\n    const reporters = plugins.reduce((prev, pluginName) => {\n      const plugin = PluginLoader.load(pluginName);\n      if (isFunction(plugin.instance?.reporter)) {\n        prev.push(plugin.instance);\n      } else if (plugin.globals?.reporter && isFunction(plugin.globals.reporter)) {\n        prev.push({\n          reporter: plugin.globals.reporter,\n          settings: plugin.globals.settings || {}\n        });\n      }\n\n      return prev;\n    }, []);\n\n    return reporters;\n  }\n\n  getTimeoutValueMs(customReporter) {\n    // global timeout for all custom reporters – set by user\n    if (this.settings.custom_reporter_timeout) {\n      return this.settings.custom_reporter_timeout;\n    }\n\n    // timeout for a specific custom reporter – set by plugin\n    if (customReporter.settings?.timeoutMs) {\n      return customReporter.settings.timeoutMs;\n    }\n\n    // default timeout when nothing is set – set by nightwatch\n    return this.settings.globals.customReporterCallbackTimeout;\n  }\n\n  callReporterFn(reporter, globalResults, {callbackTimeoutId, resolve, reject}) {\n    try {\n      if (reporter.length === 2) {\n        const reporterFnAsync = Utils.makeFnAsync(2, reporter, this.settings.globals);\n        reporterFnAsync.call(this.settings.globals, globalResults, function () {\n          clearTimeout(callbackTimeoutId);\n          resolve();\n        });\n      } else {\n        const promise = reporter.call(this.settings.globals, globalResults);\n\n        if (promise instanceof Promise) {\n          promise\n            .then(() => {\n              clearTimeout(callbackTimeoutId);\n              resolve();\n            })\n            .catch(err => {\n              clearTimeout(callbackTimeoutId);\n              reject(err);\n            });\n        } else {\n          clearTimeout(callbackTimeoutId);\n          resolve();\n        }\n      }\n    } catch (err) {\n      clearTimeout(callbackTimeoutId);\n      reject(err);\n    }\n  }\n\n  runCustomGlobalReporter(globalResults) {\n    const pluginReporters = this.getPluginReporters();\n    let customReporters;\n\n    if (Utils.isFunction(this.settings.globals.reporter))  {\n      customReporters = [{\n        reporter: this.settings.globals.reporter,\n        settings: {\n          timeoutMs: this.settings.globals.customReporterCallbackTimeout\n        }\n      }];\n    } else if (Array.isArray(this.settings.globals.reporter)) {\n      customReporters = this.settings.globals.reporter.map(reporter => {\n        if (Utils.isFunction(reporter)) {\n          return {\n            reporter,\n            settings: {\n              timeoutMs: this.settings.globals.customReporterCallbackTimeout\n            }\n          };\n        }\n\n        return reporter;\n      });\n    }\n\n    customReporters = customReporters.concat(pluginReporters);\n\n    const results = customReporters.map(customReporter => {\n      return new Promise((resolve, reject) => {\n        const callbackTimeoutId = setTimeout(() => {\n          const reporterName = customReporter.reporterName ? `\"${customReporter.reporterName}\" ` :  '';\n\n          const error = new Error(`Timeout while waiting for the custom reporter ${reporterName}to finish.`);\n          error.help = [\n            'Make sure the custom reporter calls the \"done\" callback when finished.',\n            'If the reporter is async, make sure the async operation is completed before the timeout is reached.',\n            'You can extend the timeout by defining the \"custom_reporter_timeout\" config setting in your nightwatch config file.'\n          ];\n          error.link = 'See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-reporters.html for more details.';\n\n          reject(error);\n        }, this.getTimeoutValueMs(customReporter));\n\n        const {reporter} = customReporter;\n        this.callReporterFn(reporter, globalResults, {callbackTimeoutId, resolve, reject});\n      });\n    });\n\n    return Promise.all(results);\n  }\n\n  save() {\n    if (Concurrency.isWorker()) {\n      return Promise.resolve();\n    }\n\n    return Promise.all([\n      this.runCustomGlobalReporter(this.globalResults),\n      this.writeReportToFile(this.globalResults)\n    ]);\n  }\n};\n"
  },
  {
    "path": "lib/reporter/index.js",
    "content": "const path = require('path');\nconst Utils = require('../utils');\nconst TestResults = require('./results.js');\nconst SimplifiedReporter = require('./simplified.js');\nconst {Logger, Screenshots} = Utils;\nconst {colors} = Logger;\nconst analyticsCollector = require('../utils/analytics.js');\n\nclass Reporter extends SimplifiedReporter {\n  static printAssertions(testcase) {\n    testcase.assertions.forEach(function(a) {\n      if (a.failure !== false) {\n        const message = a.stackTrace.split('\\n');\n        message.unshift(a.fullMsg);\n        Utils.showStackTrace(message.join('\\n'));\n      }\n    });\n  }\n\n  /**\n   *\n   * @param {Array} tests\n   * @param {SuiteRetries} suiteRetries\n   * @param {Object} settings\n   * @param {Object} addOpts\n   */\n  constructor({settings, tests, suiteRetries, addOpts = {}, skippedTests, allScreenedTests}) {\n    super(settings);\n\n    this.suiteRetries = suiteRetries;\n    this.suiteName = addOpts.suiteName;\n    this.testResults = new TestResults(tests, addOpts, settings, skippedTests, allScreenedTests);\n    this.currentContext = null;\n    this.__printA11Report = false;\n    this.reporter = addOpts.repoter;\n    this.isMobile = addOpts.isMobile;\n\n    this.testResults.initCurrentTest({\n      module: addOpts.moduleKey,\n      testName: '',\n      group: addOpts.groupName\n    });\n  };\n\n  /**\n   * This is the exported property on the Nightwatch api object, which is passed on to tests\n   *\n   * @return {null|object}\n   */\n  get currentTest() {\n    return this.testResults.currentTest;\n  }\n\n  get currentSection() {\n    return this.testResults.currentSection;\n  }\n\n  get printA11Report() {\n    return this.__printA11Report;\n  }\n\n  /**\n   * @param {TestCase} testcase\n   * @param {Context} context\n   */\n  setCurrentTest(testcase, context) {\n    // called for every test case (not for hooks)\n    this.currentContext = context;\n\n    this.setCurrentSection(testcase);\n    this.testResults.setCurrentTest(testcase);\n  }\n\n  setCurrentSection(testcase) {\n    // called for all global hooks, testsuite before/after hooks,\n    // and for all test cases but NOT for before_each/after_each hooks\n    // separately (considered part of the test case itself)\n    this.testResults.setCurrentSection(testcase);\n  }\n\n  markHookRun(hookName) {\n    this.testResults.markHookRun(hookName);\n  }\n\n  unmarkHookRun(hookName) {\n    this.testResults.unmarkHookRun(hookName);\n  }\n\n  setAxeResults(results) {\n    this.currentTest.results.a11y = results;\n  }\n\n  printA11yReport() {\n    this.__printA11Report = true;\n  }\n\n  resetCurrentTestName() {\n    this.testResults.resetCurrentTestName();\n  }\n\n  get unitTestsMode() {\n    return this.currentContext ? this.currentContext.unitTestsMode : this.settings.unit_tests_mode;\n  }\n\n  get currentTestCasePassed() {\n    return this.testResults.currentTestCasePassed;\n  }\n\n  get allTestsPassed() {\n    return this.testResults.testsPassed();\n  }\n\n  /**\n   * @param {Error} err\n   *\n   * @return {boolean}\n   */\n  shouldIncrementTotalCount(err) {\n    const {currentTest} = this;\n    const currentTestName = this.testResults.getCurrentTestName();\n    const shouldRetryTestcase = currentTest && this.suiteRetries && this.suiteRetries.shouldRetryTest(currentTestName);\n\n    let incrementTotalCount = err.incrementErrorCount || Utils.isUndefined(err.incrementErrorCount);\n    if (err.incrementErrorsNo || shouldRetryTestcase) {\n      incrementTotalCount = false;\n    }\n\n    return incrementTotalCount;\n  }\n\n  setFileNamePrefix(prefix) {\n    this.testResults.reportPrefix = prefix;\n  }\n\n  setSessionInfo(data) {\n    this.testResults.sessionCapabilities = data.capabilities;\n    this.testResults.sessionId = data.sessionId;\n  }\n\n  setElapsedTime() {\n    this.testResults.setElapsedTime();\n  }\n\n  setTestSectionElapsedTime() {\n    this.testResults.setTestSectionElapsedTime();\n  }\n\n  setTestStatus() {\n    this.testResults.setTestStatus();\n  }\n\n  collectTestSectionOutput() {\n    this.testResults.collectTestSectionOutput();\n  }\n\n  testSuiteFinished() {\n    this.testResults.setTotalElapsedTime();\n  }\n\n  exportResults() {\n    const results = this.testResults.export;\n\n    if (this.printA11Report) {\n      results.printA11Report = true;\n    }\n\n    return results;\n  }\n\n  ////////////////////////////////////////////////////////////\n  // Results logging\n  ////////////////////////////////////////////////////////////\n  logTestCase(testName) {\n    if (this.settings.live_output || !this.settings.parallel_mode) {\n      // eslint-disable-next-line no-console\n      console.log(`${(!this.settings.silent ? '\\n\\n' : '')}\\n  Running ${colors.green(testName)}${colors.stack_trace(':')}`);\n\n      const {columns = 100} = process.stdout;\n      // eslint-disable-next-line no-console\n      console.log(colors.stack_trace(new Array(Math.max(100, Math.floor(columns / 2))).join('─')));\n      //}\n    } else {\n      // eslint-disable-next-line no-console\n      console.log('');\n      // eslint-disable-next-line no-console\n      console.log(` – ${colors.green(testName)}\\n`);\n    }\n  }\n\n  /**\n   * @param {Object} result\n   */\n  logAssertResult(result) {\n    this.testResults.logAssertion(result);\n  }\n\n  /**\n   * @param {TheeNode} node\n   * @param {Object} result\n   */\n  logCommandResult({node, result}) {\n    try {\n      let commandResult = result;\n\n      const isSuccess =  result === undefined ||\n        result == null || result.passed ||\n        !((result instanceof Error) ||\n          (result.error instanceof Error) ||\n          result.status === -1\n        );\n\n      // Use only necessary values\n      if (result) {\n        const {status, message, showDiff, name, abortOnFailure, stack, beautifiedStack} = result;\n\n        commandResult = {\n          status,\n          message,\n          showDiff,\n          name,\n          abortOnFailure,\n          stack,\n          beautifiedStack\n        };\n\n        if (this.settings.reporter_options.save_command_result_value) {\n          if (Utils.isString(result.value) && result.value.length > 500) {\n            const filepath = path.join(this.settings.output_folder || '', 'tmp', this.testResults.uuid, `${node.fullName}_${Date.now()}.txt`);\n            commandResult.valuePath = filepath;\n\n            Utils.writeToFile(filepath, result.value);\n          } else {\n            commandResult.value = result.value;\n          }\n        }\n      }\n\n      if (this.shouldLogCommand(node)) {\n        this.testResults.logCommand({\n          name: node.fullName,\n          args: Reporter.stringifyArgs(node.args),\n          startTime: node.startTime,\n          endTime: node.endTime,\n          elapsedTime: node.elapsedTime,\n          status: isSuccess ? TestResults.TEST_PASS : TestResults.TEST_FAIL,\n          result: commandResult\n        });\n      }\n\n    } catch (e) {\n      // ignore exceptions\n    }\n  }\n\n  static stringifyArgs(args) {\n    if (Array.isArray(args)) {\n      return args.map((arg) => {\n        let stringifiedArg;\n\n        try {\n          stringifiedArg = JSON.stringify(arg);\n        } catch {\n          stringifiedArg = arg && arg.toString();\n        }\n\n        return stringifiedArg;\n      });\n    }\n\n    return args;\n  }\n\n  shouldLogCommand(node) {\n    if (!node.parent) { //root node\n      return false;\n    }\n\n    if (node.parent.isRootNode) {\n      return true;\n    }\n\n    if (node.addedInsideCallback) {\n      return true;\n    }\n\n    return false;\n  }\n\n  registerPassed(message) {\n    Logger.logDetailedMessage(`  ${colors.green(Utils.symbols.ok)} ${message}`);\n    this.testResults.incrementPassedCount();\n  }\n\n  registerFailed(err) {\n    const incrementTotal = this.shouldIncrementTotalCount(err);\n\n    this.testResults\n      .setLastError(err, {incrementTotal})\n      .incrementFailedCount(incrementTotal);\n  }\n\n  registerTestError(err) {\n    if (err.registered) {\n      return;\n    }\n\n    analyticsCollector.collectErrorEvent(err);\n\n    super.registerTestError(err);\n\n    const incrementTotal = this.shouldIncrementTotalCount(err);\n\n    this.testResults\n      .setLastError(err, {incrementTotal, addToErrArray: true})\n      .incrementErrorCount(incrementTotal);\n  }\n\n  /**\n   * Subtracts the number of passed assertions from the total assertions count\n   */\n  resetCurrentTestPassedCount() {\n    const assertionsCount = this.testResults.currentTestResult.passed;\n\n    this.testResults.subtractPassedCount(assertionsCount);\n  }\n\n  printTestResult() {\n    let ok = false;\n    if (this.testResults.currentTestCasePassed) {\n      ok = true;\n    }\n\n    const elapsedTime = this.testResults.currentTestElapsedTime;\n    const currentTestResult = this.testResults.currentTestResult;\n\n    const Concurrency = require('../runner/concurrency');\n    const isWorker = Concurrency.isWorker();\n    if (isWorker || !this.settings.detailed_output || this.unitTestsMode) {\n      this.printSimplifiedTestResult(ok, elapsedTime, isWorker);\n\n      return;\n    }\n\n    if (ok && currentTestResult.passed > 0) {\n      Logger.logDetailedMessage(`\\n  ✨ ${colors.green('PASSED.')} ${colors.green(currentTestResult.passed)} assertions. (${Utils.formatElapsedTime(elapsedTime, true)})`);\n    } else if (ok && currentTestResult.passed === 0) {\n      if (this.settings.start_session) {\n        Logger.logDetailedMessage(colors.green('No assertions ran.\\n'), 'warn');\n      }\n    } else {\n      const failureMsg = this.getFailureMessage();\n      Logger.logDetailedMessage(`\\n  ${colors.red('FAILED:')} ${failureMsg} (${Utils.formatElapsedTime(elapsedTime, true)})`);\n    }\n  }\n\n  /**\n   * @param {boolean} ok\n   * @param {number} elapsedTime\n   * @param {boolean} isWorker\n   */\n  printSimplifiedTestResult(ok, elapsedTime, isWorker) {\n    const {currentTest} = this;\n\n    const result = [colors[ok ? 'green' : 'red'](Utils.symbols[ok ? 'ok' : 'fail'])];\n    if (!this.unitTestsMode) {\n      if (isWorker) {\n        result.push(colors.bgBlack.white.bold(this.settings.testEnv));\n      }\n\n      result.push(colors.cyan('[' + this.suiteName + ']'));\n    }\n\n    const testName = currentTest.name;\n    result.push(ok ? testName : colors.red(testName));\n\n    if (elapsedTime > 20) {\n      result.push(colors.yellow.bold('(' + Utils.formatElapsedTime(elapsedTime, true) + ')'));\n    }\n\n    // eslint-disable-next-line no-console\n    console.log(result.join(' '));\n\n    if (ok || !currentTest) {\n      return;\n    }\n\n    const {results} = currentTest;\n    if (this.unitTestsMode && results.lastError) {\n      Logger.error(results.lastError);\n    } else {\n      Reporter.printAssertions(results);\n    }\n  }\n\n  getFailureMessage() {\n    const failureMsg = [];\n    const currentTestResult = this.testResults.currentTestResult;\n\n    if (currentTestResult.failed > 0){\n      failureMsg.push(`${colors.red(currentTestResult.failed)} assertions failed`);\n    }\n\n    if (currentTestResult.errors > 0) {\n      failureMsg.push(`${colors.red(currentTestResult.errors)} errors`);\n    }\n\n    if (currentTestResult.passed > 0) {\n      failureMsg.push(`${colors.green(currentTestResult.passed)} passed`);\n    }\n\n    if (currentTestResult.skipped > 0) {\n      failureMsg.push(`${colors.blue(currentTestResult.skipped)} skipped`);\n    }\n\n    return failureMsg.join(', ').replace(/,([^,]*)$/g, function(p0, p1) {\n      return ` and ${p1}`;\n    });\n  }\n\n  ////////////////////////////////////////////////////////////\n  // Screenshots\n  ////////////////////////////////////////////////////////////\n  /**\n   * @deprecated only used by JSONWire\n   * @param result\n   * @param screenshotContent\n   */\n  saveErrorScreenshot(result, screenshotContent) {\n    if (this.settings.screenshots.on_error && screenshotContent) {\n      const {currentTest} = this;\n      const prefix = `${currentTest.module}/${currentTest.name}`;\n      const fileName = Screenshots.getFileName(prefix, true, this.settings.screenshots.path);\n\n      // FIXME: make this async / handle callback\n      Screenshots.writeScreenshotToFile(fileName, screenshotContent);\n\n      this.testResults.logScreenshotFile(fileName);\n    }\n  }\n}\n\nmodule.exports = Reporter;\nmodule.exports.Simplified = require('./simplified.js');\nmodule.exports.GlobalReporter = require('./global-reporter.js');\n"
  },
  {
    "path": "lib/reporter/reporters/html.js",
    "content": "const open = require('open');\nconst path = require('path');\nconst lodashPick = require('lodash/pick');\nconst HtmlReact = require('@nightwatch/html-reporter-template');\nconst AnsiConverter = require('ansi-to-html');\n\nconst Utils = require('../../utils');\nconst BaseReporter = require('../base-reporter.js');\nconst {Logger} = Utils;\n\nclass HtmlReporter extends BaseReporter {\n  static get hookNames(){\n    return ['__before_hook', '__after_hook', '__global_beforeEach_hook', '__global_afterEach_hook'];\n  }\n\n  static get ansiConverter(){\n    return new AnsiConverter();\n  }\n\n  openReporter(fileName) {\n    return open(fileName)\n      .catch(err => {\n        Logger.error('Error opening the report: ', err.message);\n      });\n  }\n\n  getFolderPrefix() {\n    let folderPrefix = '';\n    const {folder_format} = this.options;\n    if (folder_format) {\n      if (typeof folder_format === 'function') {\n        folderPrefix = folder_format(this.results);\n      } else if (typeof folder_format === 'string') {\n        folderPrefix = folder_format;\n      }\n    }\n\n    return folderPrefix;\n  }\n\n  getFileName() {\n    let fileName = 'index';\n    const {filename_format} = this.options;\n    if (filename_format) {\n      if (typeof filename_format === 'function') {\n        fileName = filename_format(this.results);\n      } else if (typeof filename_format === 'string') {\n        fileName = filename_format;\n      }\n    }\n\n    return fileName;\n  }\n\n  computePassedAndFailedCounts(module) {\n    const result = {passedCount: 0, failedCount: 0};\n\n    if (!module || !module.completedSections) {\n      return result;\n    }\n\n    for (const sectionName of Object.keys(module.completedSections)) {\n      if (HtmlReporter.hookNames.includes(sectionName)) {\n        continue;\n      }\n\n      const section = module.completedSections[sectionName];\n      if (section.status === 'pass') {\n        result.passedCount += 1;\n      } else {\n        result.failedCount += 1;\n      }\n    }\n\n    return result;\n  }\n\n  createInitialResult(module) {\n    const {passedCount, failedCount} = this.computePassedAndFailedCounts(module);\n    const sessionCapabilities = module.sessionCapabilities || {};\n\n    return  {\n      metadata: {\n        platformName: sessionCapabilities.platformName,\n        device: 'desktop',\n        browserName: sessionCapabilities.browserName,\n        browserVersion: sessionCapabilities.browserVersion,\n        executionMode: 'local'\n      },\n      stats: {\n        passed: passedCount,\n        failed: failedCount,\n        skipped: module.skippedCount,\n        total: passedCount + failedCount + module.skippedCount,\n        time: module.timeMs\n      },\n      modules: {}\n    };\n  }\n\n  aggregateEnvironments(testEnv, moduleKey, module) {\n    const moduleName = module.name ? `${module.name} (${moduleKey})` : moduleKey;\n\n    if (!this.environments[testEnv]) {\n      this.environments[testEnv] = this.createInitialResult(module);\n    } else {\n\n      const {passedCount, failedCount} = this.computePassedAndFailedCounts(module);\n      const sessionCapabilities = module.sessionCapabilities || {};\n\n      this.environments[testEnv].stats.passed += passedCount;\n      this.environments[testEnv].stats.failed += failedCount;\n      this.environments[testEnv].stats.skipped += module.skippedCount;\n      this.environments[testEnv].stats.total += passedCount + failedCount + module.skippedCount;\n      this.environments[testEnv].stats.time += module.timeMs || this.environments[testEnv].stats.time;\n      this.environments[testEnv].metadata.platformName = this.environments[testEnv].metadata.platformName || sessionCapabilities.platformName;\n      this.environments[testEnv].metadata.browserName = this.environments[testEnv].metadata.browserName || sessionCapabilities.browserName;\n      this.environments[testEnv].metadata.browserVersion = this.environments[testEnv].metadata.browserVersion || sessionCapabilities.browserVersion;\n    }\n\n    this.environments[testEnv].modules[moduleName] = this.adaptModule(module);\n  }\n\n  aggregateStats() {\n    const startTime = new Date(this.results.startTimestamp).getTime();\n    const endTime = new Date(this.results.endTimestamp).getTime();\n\n    const stats = {\n      total: 0,\n      passed: 0,\n      failed: 0,\n      skipped: 0,\n      time: endTime - startTime\n    };\n\n    for (const envName of Object.keys(this.environments)) {\n      const env = this.environments[envName];\n\n      stats.passed += env.stats.passed;\n      stats.failed += env.stats.failed;\n      stats.skipped += env.stats.skipped;\n      stats.total += env.stats.total;\n    }\n\n    return stats;\n  }\n\n  getGlobalMetadata() {\n    return {\n      date: new Date()\n    };\n  }\n\n  adaptModule(module) {\n\n    // Pick only the necessary fields\n    const result = lodashPick(module, [\n      'completedSections',\n      'rawHttpOutput',\n      'assertionsCount',\n      'lastError',\n      'skipped',\n      'time',\n      'timeMs',\n      'errmessages',\n      'testsCount',\n      'skippedCount',\n      'failedCount',\n      'errorsCount',\n      'passedCount',\n      'group',\n      'modulePath',\n      'startTimestamp',\n      'endTimestamp',\n      'sessionCapabilities',\n      'sessionId',\n      'projectName',\n      'buildName',\n      'testEnv',\n      'isMobile',\n      'status',\n      'seleniumLog',\n      'tests',\n      'failures',\n      'errors'\n    ]);\n\n    // Convert to absolute path\n    for (const sectionName of Object.keys(result.completedSections)) {\n      const section = result.completedSections[sectionName];\n      for (const command of section.commands) {\n\n        const {output_folder} = this.options;\n        const destFolder = path.join(output_folder, this.getFolderPrefix(), 'nightwatch-html-report');\n\n        if (command.screenshot) {\n          command.screenshot = path.relative(destFolder, command.screenshot);\n        }\n\n        if (command.domSnapshot && command.domSnapshot.snapshotFilePath) {\n          command.domSnapshot.snapshotFilePath = path.resolve(process.cwd(), command.domSnapshot.snapshotFilePath);\n        }\n      }\n    }\n\n    // Add skipped tests by user in completed section\n    module.skippedByUser && module.skippedByUser.forEach(skippedTestName => {\n      module.completedSections[skippedTestName] = {\n        status: 'skip',\n        runtimeFailure: false\n      };\n    });\n\n    // Add skipped tests at runtime in completed section\n    module.skippedAtRuntime && module.skippedAtRuntime.forEach(skippedTestName => {\n      module.completedSections[skippedTestName] = {\n        status: 'skip',\n        runtimeFailure: true\n      };\n    });\n\n    return result;\n  }\n\n  adaptResults() {\n    const {modulesWithEnv}  = this.results;\n    this.environments = {};\n\n    Object.keys(modulesWithEnv).forEach((env) => {\n      const modules = modulesWithEnv[env];\n\n      // Make module paths absolute\n      this.results.modulesWithEnv[env] = Object.keys(modules).reduce((prev, value) => {\n        this.results.modulesWithEnv[env][value].modulePath = this.results.modulesWithEnv[env][value].modulePath.replace(process.cwd(), '');\n        prev[value] = this.results.modulesWithEnv[env][value];\n\n        return prev;\n      }, {});\n\n      Object.keys(modules).forEach((moduleKey) => {\n        const module = modules[moduleKey];\n        this.adaptAssertions(module);\n        this.aggregateEnvironments(env, moduleKey, module);\n      });\n    });\n\n    return {\n      environments: this.environments,\n      stats: this.aggregateStats(),\n      metadata: this.getGlobalMetadata()\n    };\n  }\n\n  async writeReport() {\n    const results = this.adaptResults();\n\n    const {output_folder, openReport: shouldOpenReport} = this.options;\n    const destFolder = path.join(output_folder, this.getFolderPrefix(), 'nightwatch-html-report');\n    const fileName = `${this.getFileName()}.html`;\n    const filePath = path.join(destFolder, `${this.getFileName()}.html`);\n\n    const jsonString = JSON.stringify(results);\n\n    HtmlReact.writeNightwatchHTMLReport(destFolder, fileName, jsonString);\n\n    Logger.logDetailedMessage(Logger.colors.stack_trace(` Wrote HTML report file to: ${path.resolve(filePath)}` + '\\n'), 'info');\n\n    if (shouldOpenReport) {\n      return this.openReporter(filePath);\n    }\n\n  }\n}\n\nmodule.exports = (function() {\n  return {\n    write(results, options, callback) {\n      const reporter = new HtmlReporter(results, options);\n\n      reporter.writeReport()\n        .then(_ => {\n          callback();\n        })\n        .catch(err => {\n          Logger.error(err);\n          callback(err);\n        });\n    },\n\n    adaptResults(results, options) {\n      const reporter = new HtmlReporter(results, options);\n\n      return reporter.adaptResults();\n    }\n  };\n})();\n"
  },
  {
    "path": "lib/reporter/reporters/json.js",
    "content": "const stripAnsi = require('strip-ansi');\nconst path = require('path');\nconst Utils = require('../../utils');\nconst {Logger} = Utils;\nconst BaseReporter = require('../base-reporter.js');\n\nclass JsonReporter extends BaseReporter {\n\n  writeReport(moduleKey, data = {}) {\n    const module = this.results.modules[moduleKey];\n    const pathParts = moduleKey.split(path.sep);\n    const moduleName = pathParts.pop();\n\n    let output_folder = this.options.output_folder;\n    let shouldCreateFolder = false;\n\n    this.adaptAssertions(module);\n\n    if (pathParts.length) {\n      output_folder = path.join(output_folder, pathParts.join(path.sep));\n      shouldCreateFolder = true;\n    }\n\n    const filename = this.options.report_filename || path.join(output_folder, `${module.reportPrefix}${moduleName}.json`);\n\n    const httpOutput = Logger.getOutput().map(item => {\n      return [item[0], stripAnsi(item[1]), item[2] || ''];\n    });\n\n    const report = {\n      report: module,\n      name: moduleName,\n      httpOutput,\n      systemerr: this.results.errmessages.map(item => stripAnsi(item)).join('\\n')\n    };\n\n    return this.writeReportFile(filename, JSON.stringify(report), shouldCreateFolder, output_folder)\n      .then(_ => {\n        Logger.info(Logger.colors.stack_trace(`Wrote JSON report file to: ${path.resolve(filename)}`));\n      });\n  }\n}\n\nmodule.exports = (function() {\n  return {\n    write(results, options) {\n      const envs = Object.keys(results.modulesWithEnv);\n      const promises = envs.map(env => {\n        const envResult = {...results, modules: results.modulesWithEnv[env]};\n        const reporter = new JsonReporter(envResult, options);\n\n        return reporter.write();\n      });\n\n      return Promise.all(promises);\n    }\n  };\n})();\n"
  },
  {
    "path": "lib/reporter/reporters/junit.js",
    "content": "/**\n * https://svn.jenkins-ci.org/trunk/hudson/dtkit/dtkit-format/dtkit-junit-model/src/main/resources/com/thalesgroup/dtkit/junit/model/xsd/junit-4.xsd\n */\n\nconst fs = require('fs');\nconst stripAnsi = require('strip-ansi');\nconst path = require('path');\nconst ejs = require('ejs');\nconst Utils = require('../../utils');\nconst BaseReporter = require('../base-reporter.js');\nconst {Logger} = Utils;\n\nlet __tmplData__ = '';\n\nclass JUnitReporter extends BaseReporter {\n  static get templateFile() {\n    return path.join(__dirname, 'junit.xml.ejs');\n  }\n\n  static set tmplData(val) {\n    __tmplData__ = val;\n  }\n\n  static get tmplData() {\n    return __tmplData__;\n  }\n\n  static loadTemplate() {\n    return new Promise((resolve, reject) => {\n      if (JUnitReporter.tmplData) {\n        return resolve(JUnitReporter.tmplData);\n      }\n\n      fs.readFile(JUnitReporter.templateFile, (err, data) => {\n        if (err) {\n          return reject(err);\n        }\n\n        JUnitReporter.tmplData = data.toString();\n        resolve(JUnitReporter.tmplData);\n      });\n    });\n  }\n\n  writeReport(moduleKey, data) {\n    const module = this.results.modules[moduleKey];\n    const pathParts = moduleKey.split(path.sep);\n    const moduleName = pathParts.pop();\n    let suiteKey = moduleName;\n    let className = moduleName;\n    if (module.name !== Utils.getTestSuiteName(moduleKey)) {\n      // module.name is not generated from moduleKey\n      className = module.name;\n    }\n    let output_folder = this.options.output_folder;\n    let shouldCreateFolder = false;\n\n    this.adaptAssertions(module);\n\n    if (pathParts.length) {\n      output_folder = path.join(output_folder, pathParts.join(path.sep));\n      suiteKey = pathParts.join('.') + '.' + moduleName;\n      if (className === moduleName) {\n        className = suiteKey;\n      }\n      shouldCreateFolder = true;\n    }\n\n    const filename = path.join(output_folder, `${module.reportPrefix}${moduleName}.xml`);\n    const report = {\n      module,\n      moduleName,\n      className,\n      suiteKey,\n      systemerr: this.results.errmessages.map(item => stripAnsi(item)).join('\\n')\n    };\n\n    let rendered = ejs.render(data, report);\n    rendered = Utils.stripControlChars(rendered);\n\n    return this.writeReportFile(filename, rendered, shouldCreateFolder, output_folder)\n      .then(_ => {\n        Logger.info(Logger.colors.stack_trace(`Wrote XML report file to: ${path.resolve(filename)}`));\n      });\n  }\n\n  write() {\n    const keys = Object.keys(this.results.modules);\n\n    return JUnitReporter.loadTemplate()\n      .then(data => {\n        const promises = keys.map(moduleKey => {\n          return this.writeReport(moduleKey, data);\n        });\n\n        return Promise.all(promises);\n      });\n  }\n}\n\nmodule.exports = (function() {\n  return {\n    write(results, options, callback) {\n\n      const envs = Object.keys(results.modulesWithEnv);\n      const promises = envs.map(env => {\n        const envResult = {...results, modules: results.modulesWithEnv[env]};\n        const reporter = new JUnitReporter(envResult, options);\n\n        return reporter.write();\n      });\n\n      Promise.all(promises)\n        .then(_ => {\n          callback();\n        })\n        .catch(err => {\n          Logger.error(err);\n\n          callback(err);\n        });\n    }\n  };\n})();\n"
  },
  {
    "path": "lib/reporter/reporters/junit.xml.ejs",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuites errors=\"<%= module.errors %>\"\n            failures=\"<%= module.failures %>\"\n            tests=\"<%= module.tests %>\">\n\n  <testsuite name=\"<%= className %>\" id=\"<%= suiteKey %>\"\n    errors=\"<%= module.errors %>\" failures=\"<%= module.failures %>\" hostname=\"\" package=\"<%= module.group || moduleName %>\" skipped=\"<%= (Array.isArray(module.skippedAtRuntime)) ? module.skippedAtRuntime.length : 0 %>\"\n    tests=\"<%= module.tests %>\" time=\"<%= module.time %>\" timestamp=\"<%= module.timestamp %>\">\n  <% for (var item in module.completed) {\n    var testcase = module.completed[item];\n    var assertions = testcase.assertions %>\n    <testcase name=\"<%= item %>\" classname=\"<%= className %>\" time=\"<%= testcase.time %>\" assertions=\"<%= assertions.length %>\"><%\n      for (var i = 0; i < assertions.length; i++) { %><% if (assertions[i].failure) { %>  <failure message=\"<%= assertions[i].message %>\"><%= assertions[i].stackTrace %></failure><% } %>\n<% if (assertions[i].screenshots && assertions[i].screenshots.length > 0) { %><system-out><% for (var j = 0; j < assertions[i].screenshots.length; j++) { %>[[ATTACHMENT|<%= assertions[i].screenshots[j] %>]]<% } %></system-out><% } %>\n    <% }\n    if (assertions.length === 0 && testcase.failed) { %>\n      <failure message=\"<%= testcase.message %>\"><%= testcase.stackTrace %></failure><% }\n    if (testcase.errors > 0 && testcase.stackTrace) { %>\n    <error <% if (testcase.lastError && testcase.lastError.message) { %>message=\"<%= testcase.lastError.message %>\" <% } %>type=\"error\"><![CDATA[\n    <%= testcase.stackTrace %>\n    ]]></error>\n    <% } %>\n    </testcase>\n  <% } %>\n\n  <% if (systemerr != '') { %>\n    <system-err>\n      <%= systemerr %>\n    </system-err>\n  <% } %>\n\n    <% if (module.lastError && Object.keys(module.completed).length === 0) { %>\n    <error message=\"<%= module.lastError.message %>\"><![CDATA[\n      <%= module.lastError.stack %>\n      ]]></error>  <% } %>\n\n  <% if (module.skippedAtRuntime && (module.skippedAtRuntime.length > 0)) { %>\n    <% for (var j = 0; j < module.skippedAtRuntime.length; j++) { %>\n    <testcase\n      name=\"<%= module.skippedAtRuntime[j] %>\" classname=\"<%= className %>\">\n      <skipped />\n    </testcase>\n    <% } %>\n  <% } %>\n  </testsuite>\n</testsuites>\n"
  },
  {
    "path": "lib/reporter/reporters/minimalJson.js",
    "content": "const lodashPick = require('lodash/pick');\nconst path = require('path');\nconst Utils = require('../../utils');\nconst {Logger} = Utils;\nconst BaseReporter = require('../base-reporter.js');\n\nclass MinimalJsonReporter extends BaseReporter {\n\n  adaptModule(module) {\n    // Pick only the necessary fields\n    const result = lodashPick(module, [\n      'modulePath',\n      'status'\n    ]);\n\n    return result;\n  }\n\n  adaptResults() {\n    const {modules}  = this.results;\n    this.modules = {};\n\n    Object.keys(modules).forEach((moduleKey) => {\n      this.modules[moduleKey] = this.adaptModule(modules[moduleKey]);\n    });\n\n    return this.modules;\n  }\n\n  writeReport() {\n    const results = this.adaptResults();\n    const {output_folder} = this.options;\n    const filename = path.join(output_folder, 'minimal_report.json');\n    const shouldCreateFolder = !Utils.dirExistsSync(output_folder);\n\n    const report = {\n      modules: results\n    };\n\n    return this.writeReportFile(filename, JSON.stringify(report), shouldCreateFolder, output_folder)\n      .then(_ => {\n        Logger.info(Logger.colors.stack_trace(`Wrote Rerun Json report file to: ${path.resolve(filename)}`));\n\n        // Setting env varaible with minimalJsonReporter path.\n        // Next time user runs nightwatch with rerun functionality, json reporter can be read from this\n        process.env.NIGHTWATCH_RERUN_REPORT_FILE = filename;\n        process.env.NEW_FOO = filename;\n      });\n  }\n}\n\nfunction write(results, options, callback) {\n  const reporter = new MinimalJsonReporter(results, options);\n\n  reporter.writeReport()\n    .then(_ => {\n      callback();\n    })\n    .catch(err => {\n      Logger.error(err);\n      callback(err);\n    });\n}\n\nmodule.exports = {\n  MinimalJsonReporter,\n  write\n};\n"
  },
  {
    "path": "lib/reporter/results.js",
    "content": "const lodashMerge = require('lodash/merge');\nconst uuid = require('uuid');\nconst Utils = require('../utils');\nconst {Logger} = Utils;\n\n// ALL THE NON-STATIC METHODS IN `Results` CLASS\n// REPRESENT SUITE LEVEL RESULTS.\nmodule.exports = class Results {\n  static get TEST_FAIL() {\n    return 'fail';\n  }\n\n  static get TEST_PASS() {\n    return 'pass';\n  }\n\n  static get TEST_SKIP() {\n    return 'skip';\n  }\n\n  constructor(tests = [], opts, settings, skippedTests = [], allScreenedTests = []) {\n    this.skippedByUser = skippedTests;\n    this.skippedAtRuntime = tests.slice(0);\n    this.testcases = {};\n    this.testSections = {};\n    this.testSectionHook = {};\n    this.isHookRunning = false;\n    this.suiteName = opts.suiteName;\n    this.moduleKey = opts.moduleKey;\n    this.modulePath = opts.modulePath;\n    this.groupName = opts.groupName;\n    this.reportPrefix = opts.reportPrefix;\n    this.testEnv = settings.testEnv;\n    this.isMobile = opts.isMobile;\n    this.globalStartTime = new Date().getTime();\n    this.startTimestamp = this.globalStartTime;\n    this.endTimestamp = this.globalStartTime;\n    this.currentTestName = '';\n    this.currentSectionName = '';\n    this.__currentTest = null;\n\n    // __initialResult is updated whenever there is no testcase result\n    // to update, so that results are not lost.\n    this.__initialResult = {\n      errors: 0,\n      failed: 0,\n      passed: 0,\n      assertions: [],\n      commands: [],\n      tests: 0\n    };\n\n    // Adding sessionInfo to reporter\n    const {capabilities = {}, desiredCapabilities = {}} = settings;\n    this.sessionCapabilities = capabilities || desiredCapabilities;\n    this.sessionId = '';\n    this.projectName = capabilities.projectName || desiredCapabilities.projectName || '';\n    this.buildName = capabilities.buildName || desiredCapabilities.buildName || '';\n    const {webdriver = {}} = settings;\n    this.host = webdriver.host || '';\n    this.name = opts.suiteName || '';\n    this.tags = opts.tags || [];\n    this.__retryTest = false;\n    this.__uuid = uuid.v4();\n\n    this.initCount(allScreenedTests);\n  }\n\n  markHookRun(hookName) {\n    // called for beforeEach, testcase, and afterEach (with the same name as `hookName`)\n    // all three above are considered to be hooks during test case execution.\n    this.isHookRunning = true;\n    this.currentTestCaseHookName = hookName;\n\n    // `testName` below would take values like: `Demo test ecosia.org__beforeEach`,\n    // `Demo test ecosia.org__testcase`, and `Demo test ecosia.org__afterEach`\n    // as `currentSectionName` would represent the test case name.\n    this.testSectionHook = this.createTestCaseResults({testName: `${this.currentSectionName}__${hookName}`});\n\n    // reset test hooks output\n    Logger.collectTestHooksOutput();\n  }\n\n  unmarkHookRun() {\n    // called for beforeEach, testcase, and afterEach during test case execution.\n    this.isHookRunning = false;\n    if (!this.currentTestCaseHookName) {\n      throw new Error('Hook run not started yet');\n    }\n\n    // below currentSection would contain the result data for the complete\n    // test case run, including beforeEach & afterEach.\n    // Ex. for `Demo test ecosia.org` test case.\n    const currentSection = this.currentSection;\n\n    // hookdata would contain the result data for the individual\n    // beforeEach/testcase/afterEach hook run inside the current\n    // section (test case).\n    const hookdata = this.testSectionHook;\n\n    const startTime = hookdata.startTimestamp;\n    const endTime = new Date().getTime();\n    const elapsedTime = endTime - startTime;\n    hookdata.endTimestamp = endTime;\n\n    hookdata.time = (elapsedTime / 1000).toPrecision(4);\n    hookdata.timeMs = elapsedTime;\n\n    hookdata.httpOutput = Logger.collectTestHooksOutput();\n\n    if (hookdata.errors > 0 || hookdata.failed > 0) {\n      hookdata.status = Results.TEST_FAIL;\n    }\n\n    currentSection[this.currentTestCaseHookName] = hookdata;\n  }\n\n  get initialResult() {\n    return this.__initialResult;\n  }\n\n  // currentTest --> current or most recently run test case\n  get currentTestResult() {\n    // `this.currentTest.name` is only set after first test case is run.\n    // before that, `this.currentTest.name` is '', so `this.initialResult`\n    // is returned by this getter.\n    const testName = this.currentTest.name;\n\n    return this.getTestResult(testName, {returnFullResult: true});\n  }\n\n  get uuid() {\n    return this.__uuid;\n  }\n\n  /**\n   * @param {TestCase} value\n   */\n  set currentTest(value) {\n    this.__currentTest = value;\n  }\n\n  getTestResult(testName, {returnFullResult = false} = {}) {\n    if (!testName || !this.testcases[testName]) {\n      return this.initialResult;\n    }\n\n    const currentTest = this.testcases[testName];\n\n    if (returnFullResult) {\n      currentTest.steps = this.skippedAtRuntime;\n      currentTest.stackTrace = this.stackTrace;\n      // adds details of all test cases ran till now to the current test case result.\n      currentTest.testcases = Object.keys(this.testcases).reduce((prev, key) => {\n        prev[key] = Object.keys(this.testcases[key]).reduce((prevVal, prop) => {\n          if (prop !== 'testcases') {\n            prevVal[prop] = this.testcases[key][prop];\n          }\n          if (prop === 'assertions') {\n            prevVal.tests = this.testcases[key].assertions;\n          }\n\n          return prevVal;\n        }, {});\n\n        return prev;\n      }, {});\n    }\n\n    return currentTest;\n  }\n\n  getTestSection(testName) {\n    if (!testName || !this.testSections[testName]) {\n      return this.initialResult;\n    }\n\n    return this.testSections[testName];\n  }\n\n  /**\n   * @return {TestCase}\n   */\n  getCurrentTest() {\n    // returns the current/most recent testcase object (not testcase result)\n    return this.__currentTest;\n  }\n\n  get currentTest() {\n    // returns the current/most recent testcase object (not testcase result)\n    if (!this.__currentTest) {\n      return null;\n    }\n\n    const name = this.__currentTest.testName;\n\n    return {\n      name,\n      module: this.moduleKey,\n      group: this.groupName,\n      results: this.getTestResult(name, {returnFullResult: true}),\n      timestamp: this.timestamp\n    };\n  }\n\n  get currentSection() {\n    // returns the current/most recently run test section result.\n    // this will only return `this.initialResult` if called before the global\n    // beforeEach hook is run because we never reset `this.currentSectionName`.\n    return this.getTestSection(this.currentSectionName);\n  }\n\n  testSectionHasFailures(testSection) {\n    return testSection.errors > 0 || testSection.failed > 0;\n  }\n\n  ////////////////////////////////////////////////////////////\n  // Counters\n  ////////////////////////////////////////////////////////////\n  get passedCount() {\n    return this.__passedCount;\n  }\n\n  get failedCount() {\n    return this.__failedCount;\n  }\n\n  get errorsCount() {\n    return this.__errorsCount;\n  }\n\n  get skippedCount() {\n    return this.__skippedCount;\n  }\n\n  get timestamp() {\n    return this.__timestamp;\n  }\n\n  get testsCount() {\n    return this.__testsCount;\n  }\n\n  get lastError() {\n    return this.__lastError;\n  }\n\n  get stackTrace() {\n    return (this.__lastError && this.__lastError instanceof Error) ? this.__lastError.stack : '';\n  }\n\n  get currentTestElapsedTime() {\n    return this.currentTestResult.timeMs;\n  }\n\n  get currentTestCasePassed() {\n    return this.currentTestResult.errors === 0 && this.currentTestResult.failed === 0;\n  }\n\n  get currentTestCaseHasFailures() {\n    // 'currentTestCase' represents current or most recently run test case.\n    return this.currentTestResult.errors > 0 || this.currentTestResult.failed > 0;\n  }\n\n  /**\n   * Exports the complete results for the entire testsuite\n   *\n   * @return {object}\n   */\n  get export() {\n    let lastError = null;\n    const {moduleKey, reportPrefix} = this;\n\n    const suiteResults = {\n      moduleKey,\n      hasFailures: !this.testsPassed(),\n      results: {\n        uuid: this.uuid,\n        reportPrefix,\n        // if no this.currentTestName is present at the time (which happens\n        // before any test cases started running or after all test cases are\n        // done running), all executed assertions are saved to `this.initialResult`.\n        assertionsCount: this.initialResult.assertions.length\n      }\n    };\n\n    Object.keys(this.testcases).forEach(key => {\n      const testcase = this.testcases[key];\n      if (testcase.lastError) {\n        //lastError = testcase.lastError;\n      }\n      suiteResults.results.assertionsCount += testcase.assertions.length;\n    });\n\n    if (!lastError && this.lastError) {\n      lastError = this.lastError;\n    }\n\n    suiteResults.results.lastError = lastError;\n    suiteResults.results.skippedAtRuntime = this.skippedAtRuntime;\n    suiteResults.results.skippedByUser = this.skippedByUser;\n    suiteResults.results.skipped = [...this.skippedAtRuntime, ...this.skippedByUser];\n    suiteResults.results.time = this.time;\n    suiteResults.results.timeMs = this.timeMs;\n    suiteResults.results.completed = this.testcases;\n    suiteResults.results.completedSections = this.testSections;\n    suiteResults.results.errmessages = this.errmessages;\n    suiteResults.results.testsCount = this.testsCount;\n    suiteResults.results.skippedCount = this.skippedCount;\n    suiteResults.results.failedCount = this.failedCount;\n    suiteResults.results.errorsCount = this.errorsCount;\n    suiteResults.results.passedCount = this.passedCount;\n    suiteResults.results.group = this.groupName;\n    suiteResults.results.modulePath = this.modulePath;\n    suiteResults.results.startTimestamp = new Date(this.startTimestamp).toUTCString();\n    suiteResults.results.endTimestamp = new Date(this.endTimestamp).toUTCString();\n    suiteResults.results.sessionCapabilities = this.sessionCapabilities;\n    suiteResults.results.sessionId = this.sessionId;\n    suiteResults.results.projectName = this.projectName;\n    suiteResults.results.buildName = this.buildName;\n    suiteResults.results.testEnv = this.testEnv;\n    suiteResults.results.isMobile = this.isMobile;\n    suiteResults.results.status = this.getTestStatus();\n    suiteResults.results.seleniumLog = this.seleniumLog;\n    suiteResults.results.host = this.host;\n    suiteResults.results.name = this.name;\n    suiteResults.results.tags = this.tags;\n\n    // Backwards compat\n    suiteResults.results.tests = this.testsCount;\n    suiteResults.results.failures = this.failedCount;\n    suiteResults.results.errors = this.errorsCount;\n    suiteResults.results.group = this.groupName;\n\n    return suiteResults;\n  }\n\n  initCurrentTest(testcase) {\n    this.currentTest = testcase;\n\n    return this;\n  }\n\n  resetCurrentTestName() {\n    // called after all test cases in a test suite are executed.\n\n    // FIXME: in v2, this needs to be this.__currentTest.testName, but it isn't desirable now because will make\n    //  client.currentTest.name empty in the after() hook and potentially introduce breaking changes\n    //this.__currentTest.testName = '';\n\n    this.currentTestName = '';\n  }\n\n  resetCurrentSectionName() {\n    // never called, which helps `this.currentSection` always return\n    // a valid test section result.\n    this.currentSectionName = '';\n  }\n\n  getCurrentTestName() {\n    // FIXME: see resetCurrentTestName()\n    const {testName} = this.getCurrentTest() || {};\n\n    return this.currentTestName;\n  }\n\n  set retryTest(value) {\n    this.__retryTest = value;\n  }\n\n  get retryTest() {\n    return this.__retryTest;\n  }\n\n  /**\n   * @param {TestCase} testcase\n   * @return {Object}\n   */\n  createTestCaseResults(testcase) {\n    const result = {\n      time: 0,\n      assertions: [],\n      commands: [],\n      passed: 0,\n      errors: 0,\n      failed: 0,\n      retries: testcase.retriesCount,\n      skipped: 0,\n      tests: 0,\n      status: Results.TEST_PASS,\n      startTimestamp: new Date().getTime(),\n      httpOutput: []\n    };\n\n    if (this.retryTest && this.testSections[testcase.testName]) {\n      const retryTestData = this.testSections[testcase.testName];\n\n      result['retryTestData'] = [retryTestData];\n\n      if (retryTestData['retryTestData']) {\n        result['retryTestData'].push(...retryTestData['retryTestData']);\n\n        delete retryTestData['retryTestData'];\n      }\n\n      this.retryTest = false;\n    }\n\n    return result;\n  }\n\n  resetLastError() {\n    this.__lastError = null;\n  }\n\n  setLastError(err, {incrementTotal, addToErrArray = false} = {}) {\n    const testName = this.getCurrentTestName();\n    this.__lastError = err;\n\n    if (testName && this.testcases[testName]) {\n      this.testcases[testName].lastError = err;\n\n      if (addToErrArray) {\n        this.testcases[testName].errorsPerTest = this.testcases[testName].errorsPerTest || [];\n        this.testcases[testName].errorsPerTest.push(err.message);\n      }\n    }\n\n    const detailedLogging = err.detailedLogging || Utils.isUndefined(err.detailedLogging);\n    if ((!testName || addToErrArray) && incrementTotal && detailedLogging) {\n      const errorMessage = Logger.getErrorContent(err, this.modulePath);\n      this.errmessages.push(errorMessage);\n    }\n\n    return this;\n  }\n\n  /**\n   * @param {Boolean} incrementTotal\n   * @return {Results}\n   */\n  incrementErrorCount(incrementTotal = true) {\n    if (incrementTotal) {\n      this.__errorsCount++;\n    }\n\n    const result = this.getTestResult(this.currentTestName);\n    result.errors++;\n\n    // also increment errors count for the current section\n    this.currentSection.errors++;\n\n    if (this.isHookRunning) {\n      // A test case's beforeEach/testcase/afterEach hook is running,\n      // not a before/after hook or global beforeEach/afterEach hook.\n      this.testSectionHook.errors++;\n    }\n\n    return this;\n  }\n\n  /**\n   * @param {Boolean} incrementTotal\n   * @return {Results}\n   */\n  incrementFailedCount(incrementTotal = true) {\n    if (incrementTotal) {\n      this.__failedCount++;\n    }\n\n    const result = this.getTestResult(this.currentTestName);\n    result.failed++;\n\n    // also increment failed count for the current section\n    this.currentSection.failed++;\n\n    if (this.isHookRunning) {\n      this.testSectionHook.failed++;\n    }\n\n    return this;\n  }\n\n  incrementPassedCount() {\n    this.__passedCount++;\n\n    const result = this.getTestResult(this.currentTestName);\n    result.passed++;\n\n    // also increment passed count for the current section\n    this.currentSection.passed++;\n\n    if (this.isHookRunning) {\n      this.testSectionHook.passed++;\n    }\n\n    return this;\n  }\n\n  subtractPassedCount(count = 0) {\n    this.__passedCount = this.__passedCount - count;\n\n    return this;\n  }\n\n  /**\n   * @param {Object} assertion\n   * @return {module.Results}\n   */\n  logAssertion(assertion) {\n    const result = this.getTestResult(this.currentTestName);\n    result.assertions.push(assertion);\n\n    // backwards compatibility\n    result.tests++;\n\n    return this;\n  }\n\n  logCommand(command) {\n    const result = this.currentSection;\n    result.commands.push(command);\n\n    if (this.isHookRunning) {\n      // A test case's beforeEach/testcase/afterEach hook is running,\n      // not a before/after hook or global beforeEach/afterEach hook.\n      this.testSectionHook.commands.push(command);\n    }\n\n    return this;\n  }\n\n  initCount(allScreenedTests) {\n    this.__passedCount = 0;\n    this.__failedCount = 0;\n    this.__errorsCount = 0;\n    this.__skippedCount = allScreenedTests.length;\n    this.__testsCount = 0;\n    this.__timestamp = new Date().toUTCString();\n    this.errmessages = [];\n    this.time = 0;\n  }\n\n  setElapsedTime() {\n    const currentTest = this.getCurrentTest();\n    const startTime = currentTest ? currentTest.startTime : this.globalStartTime;\n    const endTime = new Date().getTime();\n    const elapsedTime = endTime - startTime;\n    this.endTimestamp = endTime;\n\n    if (currentTest) {\n      this.currentTestResult.time = (elapsedTime / 1000).toPrecision(4);\n      this.currentTestResult.timeMs = elapsedTime;\n      this.currentTestResult.startTimestamp = new Date(startTime).toUTCString();\n      this.currentTestResult.endTimestamp = new Date(endTime).toUTCString();\n    }\n\n    return this;\n  }\n\n  setTestSectionElapsedTime() {\n    const currentSection = this.currentSection;\n    const startTime = currentSection?.startTimestamp || this.globalStartTime;\n    const endTime = new Date().getTime();\n    const elapsedTime = endTime - startTime;\n    this.endTimestamp = endTime;\n\n    this.time += elapsedTime;\n\n    if (currentSection) {\n      currentSection.time = (elapsedTime / 1000).toPrecision(4);\n      currentSection.timeMs = elapsedTime;\n      currentSection.startTimestamp = startTime;\n      currentSection.endTimestamp = endTime;\n\n    }\n\n    return this;\n  }\n\n  setTestStatus() {\n    // run for all test cases and hooks (except for [before|after]_each hooks)\n    // ^ [before|after]_each hooks are considered part of the test case itself\n    const currentTest = this.getCurrentTest();\n    if (!currentTest) {\n      return;\n    }\n\n    if (this.currentTestCaseHasFailures) {\n      this.currentTestResult.status = Results.TEST_FAIL;\n    } else {\n      this.currentTestResult.status = Results.TEST_PASS;\n    }\n\n    // also set status for the current section\n    const currentSection = this.currentSection;\n    if (this.testSectionHasFailures(currentSection)) {\n      currentSection.status = Results.TEST_FAIL;\n    } else {\n      currentSection.status = Results.TEST_PASS;\n    }\n  }\n\n  collectTestSectionOutput() {\n    const currentSection = this.currentSection;\n    if (!currentSection) {\n      return;\n    }\n\n    currentSection.httpOutput = Logger.collectTestSectionOutput();\n  }\n\n  setTotalElapsedTime() {\n    this.timeMs = this.time;\n    this.time = (this.time / 1000).toPrecision(4);\n\n    return this;\n  }\n\n  /**\n   * Sets the currently running testcase\n   *\n   * @param {TestCase} testcase\n   * @return {Results}\n   */\n  setCurrentTest(testcase) {\n    // we set this during `runCurrentTest` method call in `testsuite/index.js`\n    // only called for test cases (not for hooks)\n    this.currentTest = testcase;\n\n    const testName = testcase.testName;\n    this.currentTestName = testName;\n    this.testcases[testName] = this.createTestCaseResults(testcase);\n\n    const index = this.skippedAtRuntime.indexOf(testName);\n    if (index > -1) {\n      this.skippedAtRuntime.splice(index, 1);\n      this.__skippedCount -= 1;\n    }\n\n    this.__testsCount++;\n\n    return this;\n  }\n\n  setCurrentSection(testcase) {\n    // set for all tests and hooks (except [before|after]_each hooks)\n    // ^ [before|after]_each hooks are considered part of the test case itself\n    this.currentSectionName = testcase.testName;\n    this.testSections[testcase.testName] = this.createTestCaseResults(testcase);\n  }\n\n  setSeleniumLogFile(outputFilePath) {\n    this.seleniumLog = outputFilePath;\n  }\n\n  logScreenshotFile(screenshotFile) {\n    const assertions = this.currentTestResult.assertions;\n    const lastAssertion = assertions[assertions.length - 1];\n\n    if (lastAssertion) {\n      lastAssertion.screenshots = lastAssertion.screenshots || [];\n      lastAssertion.screenshots.push(screenshotFile);\n    }\n  }\n\n  testsPassed() {\n    return this.failedCount === 0 && this.errorsCount === 0;\n  }\n\n  getTestStatus() {\n    // returns suite level test status.\n    if (this.failedCount > 0 || this.errorsCount > 0) {\n      return Results.TEST_FAIL;\n    }\n\n    if (this.passedCount > 0) {\n      return Results.TEST_PASS;\n    }\n\n    return Results.TEST_SKIP;\n  }\n\n\n  /**\n   * Appends data in current testSections data.\n   *\n   * @param {Object} data\n   */\n  appendTestResult(data) {\n    lodashMerge(this.testSections, data);\n  }\n\n  /**\n   * Combines all the individual test suite reports into a global one\n   *\n   * @param {Array} suiteResultsArr\n   * @param {Object} initialReport\n   * @return {Object}\n   */\n  static createGlobalReport(suiteResultsArr, initialReport) {\n    return suiteResultsArr.reduce((prev, item) => {\n      const results = item.results;\n\n      if (results.lastError) {\n        prev.lastError = results.lastError;\n      }\n\n      // Accumulating stats\n      prev.passed += results.passedCount;\n      prev.failed += results.failedCount;\n      prev.errors += results.errorsCount;\n      prev.skipped += results.skippedCount;\n      prev.assertions += results.assertionsCount;\n\n      // Accumulating error messages\n      if (Array.isArray(results.errmessages) && results.errmessages.length > 0) {\n        prev.errmessages = prev.errmessages.concat(results.errmessages);\n      }\n\n      results.httpOutput = item.httpOutput || [];\n      results.rawHttpOutput = item.rawHttpOutput || [];\n      prev.modules[item.moduleKey] = results;\n      prev.modulesWithEnv[item.results.testEnv] = prev.modulesWithEnv[item.results.testEnv] || {};\n      prev.modulesWithEnv[item.results.testEnv][item.moduleKey] = results;\n\n      return prev;\n    }, initialReport);\n  }\n\n  get eventDataToEmit() {\n    const {testEnv, sessionCapabilities, sessionId, tags, modulePath, name, host} = this;\n\n    return {\n      envelope: this.testSections,\n      metadata: {\n        testEnv, sessionCapabilities, sessionId, tags, modulePath, name, host\n      }\n    };\n  }\n};\n"
  },
  {
    "path": "lib/reporter/simplified.js",
    "content": "const Utils = require('../utils');\nconst {Logger} = Utils;\n\nclass SimplifiedReporter {\n  static logError(err) {\n    if (!Utils.isErrorObject(err)) {\n      if (Utils.isObject(err)) {\n        err = Object.keys(err).length > 0 ? JSON.stringify(err) : '';\n      }\n\n      err = new Error(err.message || err);\n    }\n\n    Logger.error(err);\n  }\n\n  get currentTestCase() {\n    return null;\n  }\n\n  /**\n   * @param {Object} settings\n   */\n  constructor(settings) {\n    this.settings = settings;\n    this.currentContext = null;\n  }\n\n  logAssertResult(test) {\n    return this;\n  }\n\n  /**\n   * @param {Object} result\n   */\n  logCommandResult(node, result) {\n    return this;\n  }\n\n  logFailedAssertion(err) {\n    Logger.logDetailedMessage(`  ${Logger.colors.red(Utils.symbols.fail)} ${err.message}`);\n\n    let sections = err.stack.split('\\n');\n    Logger.logDetailedMessage(`${Logger.colors.stack_trace(sections.join('\\n'))} \\n`);\n  }\n\n  registerPassed(message) {\n    Logger.logDetailedMessage(`${Logger.colors.green(Utils.symbols.ok)} ${message}`);\n  }\n\n  registerFailed(err) {\n    return this;\n  }\n\n  registerTestError(err) {}\n  saveErrorScreenshot(result, screenshotContent) {}\n}\n\nmodule.exports = SimplifiedReporter;\n"
  },
  {
    "path": "lib/reporter/summary.js",
    "content": "const Utils = require('../utils');\nconst {Logger} = Utils;\nconst {colors} = Logger;\n\nmodule.exports = class Summary {\n  static failed(test) {\n    return test.failures > 0 || test.failed > 0 || test.errors > 0;\n  }\n\n  static getTestcaseHeader(testcase, testcaseName) {\n    const triesCount = testcase.retries > 0 ? ` x ${testcase.retries + 1}` : '';\n    const triesContent = testcase.retries > 0 ? ` - ${triesCount} tries` : '';\n    const title = `\\n   ${colors.light_cyan('–')} ${colors.light_cyan(testcaseName)} `;\n\n    const details = (testcase.timeMs ? colors.stack_trace(`(${Utils.formatElapsedTime(testcase.timeMs)}${triesCount})`) : '') + triesContent;\n\n    return `${title}${details}\\n`;\n  }\n\n  /**\n   * @param {object} testSuite\n   * @param {string} testSuiteName\n   * @param {number} index\n   * @param {boolean} startSessionEnabled\n   * @return {[string]}\n   */\n  static getFailedSuiteContent({testSuite, testSuiteName, index = 0, startSessionEnabled = true}) {\n    const testcases = Object.keys(testSuite.completed);\n    const initial = [colors.red(`   ${Utils.symbols.fail} ${index + 1}) ${testSuiteName}`)];\n\n    return testcases.reduce((prev, name) => {\n      const testcase = testSuite.completed[name];\n\n      if (Summary.failed(testcase)) {\n        prev.push(Summary.getTestcaseHeader(testcase, name));\n\n        let content;\n        if (Summary.shouldPrintAssertions(testcase) && startSessionEnabled) {\n          content = Logger.getFailedAssertions(testcase.assertions, testSuite.modulePath);\n        } else if (testcase.lastError) {\n          content = '  ' + Logger.getErrorContent(testcase.lastError, testSuite.modulePath);\n        }\n\n        if (content) {\n          prev.push(content);\n          testSuite.globalErrorRegister.push(content);\n        }\n      } else if (testcase.lastError) {\n        prev.push(Logger.getErrorContent(testcase.lastError, testSuite.modulePath));\n      }\n\n      return prev;\n    }, initial);\n  }\n\n  /**\n   * @param {Array} content\n   */\n  static printSuite(content) {\n    content.forEach(line => {\n      if (Utils.isObject(line) && line.stacktrace) {\n        Utils.showStackTrace(line.content);\n      } else {\n        // eslint-disable-next-line no-console\n        console.log(line);\n      }\n    });\n  }\n\n  /**\n   * @param {object} testSuite\n   */\n  static printErrors(testSuite) {\n    if (Array.isArray(testSuite.errmessages)) {\n      testSuite.errmessages = testSuite.errmessages.reduce((prev, val) => {\n        if (testSuite.globalErrorRegister && !testSuite.globalErrorRegister.includes(val)) {\n          testSuite.globalErrorRegister.push(val);\n          prev.push(val);\n        }\n\n        return prev;\n      }, []);\n\n      if (testSuite.errmessages.length > 0) {\n        // eslint-disable-next-line no-console\n        console.log(colors.stack_trace('\\n  - OTHER ERRORS:'));\n      }\n\n      testSuite.errmessages.forEach(function(errorMessage, index) {\n        // eslint-disable-next-line no-console\n        Logger.error(errorMessage);\n      });\n    }\n  }\n\n  /**\n   * @param {object} testSuite\n   */\n  static printSkipped(testSuite) {\n    if (testSuite.skippedAtRuntime.length > 0) {\n      // eslint-disable-next-line no-console\n      console.log(colors.cyan('    SKIPPED (at runtime):'));\n      testSuite.skippedAtRuntime.forEach(function(testcase) {\n        // eslint-disable-next-line no-console\n        console.log(`    - ${testcase}`);\n      });\n    }\n\n    if (testSuite.skippedByUser.length > 0) {\n      // eslint-disable-next-line no-console\n      console.log(colors.cyan('    SKIPPED (by user):'));\n      testSuite.skippedByUser.forEach(function(testcase) {\n        // eslint-disable-next-line no-console\n        console.log(`    - ${testcase}`);\n      });\n    }\n  }\n\n  constructor(settings) {\n    this.settings = settings;\n  }\n\n  static shouldPrintAssertions(testcase) {\n    return testcase.assertions.length > 0;\n  }\n\n  print(globalResults) {\n    const testSuites = Object.keys(globalResults.modules);\n    const testSuitesCount = testSuites.length;\n\n    let failedIndex = 0;\n    testSuites.forEach((testSuiteName, index) => {\n      const testSuite = globalResults.modules[testSuiteName];\n\n      if (Summary.failed(testSuite)) {\n        testSuite.globalErrorRegister = [];\n\n        Summary.printSuite(Summary.getFailedSuiteContent({\n          testSuite,\n          index: failedIndex++,\n          testSuiteName,\n          startSessionEnabled: this.settings.start_session\n        }));\n\n        Summary.printErrors(testSuite);\n        Summary.printSkipped(testSuite);\n      }\n    });\n\n    if (testSuites.length === 0) {\n      Summary.printErrors(globalResults);\n    }\n  }\n};\n"
  },
  {
    "path": "lib/runner/androidEmulator.js",
    "content": "const {getSdkRootFromEnv, AndroidBinaryError, requireMobileHelper} = require('../utils/mobile.js');\nconst {killEmulatorWithoutWait, getAlreadyRunningAvd, launchAVD, getPlatformName} = requireMobileHelper();\n\nmodule.exports = class AndroidServer {\n\n  constructor (AVD) {\n    this.sdkRoot = getSdkRootFromEnv();\n    this.avd = AVD || 'nightwatch-android-11';\n    this.emulatorId = '';\n    this.emulatorAlreadyRunning = false;\n  }\n\n  async killEmulator() {\n    return killEmulatorWithoutWait(this.sdkRoot, getPlatformName(), this.emulatorId);\n  }\n\n  async launchEmulator() {\n    try {\n      const emulatorId = await getAlreadyRunningAvd(this.sdkRoot, getPlatformName(), this.avd);\n      this.emulatorAlreadyRunning = !!emulatorId;\n\n      this.emulatorId = emulatorId || await launchAVD(this.sdkRoot, getPlatformName(), this.avd);\n\n      if (this.emulatorId === null) {\n        throw new Error('Failed to launch AVD inside Android Emulator');\n      }\n    } catch (err) {\n      throw new AndroidBinaryError(err.message, 'emulator');\n    }\n  }\n};\n"
  },
  {
    "path": "lib/runner/cli/argv-setup.js",
    "content": "const path = require('path');\nconst minimist = require('minimist');\n\nconst DefaultSettings = require('../../settings/defaults.js');\nconst {Logger} = require('../../utils');\n\nmodule.exports = new (function () {\n  /**\n   * Based on https://github.com/substack/node-optimist by\n   *  James Halliday (mail@substack.net), which has been deprecated\n   */\n  class ArgvSetup {\n    get argv() {\n      const argv = minimist(this.__processArgs, this.options);\n      argv.$0 = this.$0;\n\n      if (this.demanded._ && argv._.length < this.demanded._) {\n        this.fail(`Not enough non-option arguments: got ${argv._.length}, need at least ${this.demanded._}`);\n      }\n\n      const missing = [];\n      Object.keys(this.demanded).forEach(function (key) {\n        if (!argv[key]) {\n          missing.push(key);\n        }\n      });\n\n      if (missing.length) {\n        this.fail('Missing required arguments: ' + missing.join(', '));\n      }\n\n      return argv;\n    }\n\n    constructor(processArgs, cwd = process.cwd()) {\n      this.options = {\n        alias: {},\n        default: {}\n      };\n\n      this.__processArgs = processArgs;\n      this.usage = null;\n      this.demanded = {};\n      this.descriptions = {};\n\n      this.$0 = process.argv.slice(0, 2)\n        .map(function (x) {\n          const b = rebase(cwd, x);\n\n          return x.match(/^\\//) && b.length < x.length ? b : x;\n        }).join(' ');\n\n      if (process.env._ !== undefined && process.argv[1] === process.env._) {\n        this.$0 = process.env._.replace(path.dirname(process.execPath) + '/', '');\n      }\n    }\n\n    addDefault(key, value) {\n      if (typeof key === 'object') {\n        Object.keys(key).forEach((k) => {\n          this.addDefault(k, key[k]);\n        });\n      } else {\n        this.options.default[key] = value;\n      }\n\n      return this;\n    }\n\n    isDefault(option, value) {\n      return this.options.default[option] && this.options.default[option] === value;\n    }\n\n    getDefault(option) {\n      return this.options.default[option];\n    }\n\n    alias(x, y) {\n      if (typeof x === 'object') {\n        Object.keys(x).forEach((key) => {\n          this.alias(key, x[key]);\n        });\n      } else {\n        this.options.alias[x] = (this.options.alias[x] || []).concat(y);\n      }\n\n      return this;\n    }\n\n    demand(keys) {\n      if (typeof keys == 'number') {\n        if (!this.demanded._) {\n          this.demanded._ = 0;\n        }\n        this.demanded._ += keys;\n      } else if (Array.isArray(keys)) {\n        keys.forEach((key) => {\n          this.demand(key);\n        });\n      } else {\n        this.demanded[keys] = true;\n      }\n\n      return this;\n    }\n\n    showUsage(msg) {\n      this.usage = msg;\n\n      return this;\n    }\n\n    describe(key, desc, groupName) {\n      if (typeof key === 'object') {\n        Object.keys(key).forEach((k) => {\n          this.describe(k, key[k], groupName);\n        });\n      } else {\n        this.descriptions[key] = {desc, groupName};\n      }\n\n      return this;\n    }\n\n    option(key, opt) {\n      if (typeof key === 'object') {\n        Object.keys(key).forEach((k) => {\n          this.option(k, key[k]);\n        });\n      } else {\n        if (opt.alias) {\n          this.alias(key, opt.alias);\n        }\n\n        if (opt.demand) {\n          this.demand(key);\n        }\n\n        if (typeof opt.defaults !== 'undefined') {\n          this.addDefault(key, opt.defaults);\n        }\n\n        const desc = opt.describe || opt.description || opt.desc;\n        if (desc) {\n          this.describe(key, desc, opt.group);\n        }\n      }\n\n      return this;\n    }\n\n    showHelp(fn) {\n      if (!fn) {\n        fn = console.error;\n      }\n\n      fn(this.help());\n    }\n\n    help() {\n      const keys = Object.keys(this.descriptions);\n      const groups = Object.keys(this.descriptions).reduce((prev, key) => {\n        const group = this.descriptions[key].groupName || 'Main options';\n        prev[group] = prev[group] || [];\n        prev[group].push(key);\n\n        return prev;\n      }, {});\n\n      const help = [];\n\n      if (this.usage) {\n        help.unshift(this.usage.replace(/\\$0/g, this.$0), '');\n      }\n\n      const switches = keys.reduce((acc, key) => {\n        acc[key] = [key].concat(this.options.alias[key] || [])\n          .map(function (sw) {\n            return (sw.length > 1 ? '--' : '-') + sw;\n          })\n          .join(', ');\n\n        return acc;\n      }, {});\n\n      const switchlen = longest(Object.keys(switches).map(function (s) {\n        return switches[s] || '';\n      }));\n\n      const desclen = longest(Object.keys(this.descriptions).map((d) => {\n        return this.descriptions[d].desc || '';\n      }));\n\n      Object.keys(groups).forEach((groupName, index) => {\n        const content = ['\\n'];\n        content.push(Logger.colors.brown(groupName + ':'));\n\n        groups[groupName].forEach(key => {\n          const kswitch = switches[key];\n          let desc = this.descriptions[key].desc || '';\n          const spadding = new Array(Math.max(switchlen - kswitch.length + 3, 0)).join('.');\n          const dpadding = new Array(Math.max(desclen - desc.length + 1, 0)).join(' ');\n\n          if (dpadding.length > 0) {\n            desc += dpadding;\n          }\n\n          const prelude = '  ' + (kswitch) + ' ' + Logger.colors.stack_trace(spadding);\n\n          const extra = [\n            this.demanded[key]\n              ? '[required]'\n              : null,\n            this.options.default[key] !== undefined\n              ? '[default: ' + JSON.stringify(this.options.default[key]) + ']'\n              : null\n          ].filter(Boolean).join('  ');\n\n          const body = [desc, extra].filter(Boolean).join('  ');\n\n          content.push(prelude + ' ' + Logger.colors.stack_trace(body));\n        });\n\n        help.push(content.join('\\n'));\n      });\n\n      help.push('\\n');\n\n      return help.join('');\n    }\n\n    fail(msg) {\n      if (msg) {\n        console.error(Logger.colors.red(msg) + '\\n');\n      }\n\n      this.showHelp();\n\n      process.exit(1);\n    }\n\n    setup() {\n      // CLI definitions\n      this.option('source', {\n        string: true\n      });\n\n      // $ nightwatch -e\n      // $ nightwatch --env saucelabs\n      this.option('env', {\n        description: 'Specify the testing environment to use.',\n        alias: 'e',\n        defaults: 'default'\n      });\n\n      // $ nightwatch -c\n      // $ nightwatch --config\n      this.option('config', {\n        demand: true,\n        description: 'Path to configuration file; nightwatch.conf.js or nightwatch.json are read by default if present.',\n        alias: 'c',\n        defaults: './nightwatch.json'\n      });\n\n      // $ nightwatch -t\n      // $ nightwatch --test\n      this.option('test', {\n        description: 'Runs a single test.',\n        alias: 't'\n      });\n\n      // $ nightwatch --testcase\n      this.option('testcase', {\n        description: 'Used only together with --test. Runs the specified testcase from the current suite/module.'\n      });\n\n      // $ nightwatch --mocha\n      this.option('mocha', {\n        description: 'Set the test runner to use Mocha.'\n      });\n\n      /*\n      // $ nightwatch --chrome\n      this.option('chrome', {\n        group: 'Browsers',\n        description: 'Run tests in Google Chrome browser'\n      });\n\n      // $ nightwatch --firefox\n      this.option('firefox', {\n        group: 'Browsers',\n        description: 'Run tests in Mozilla Firefox browser'\n      });\n\n      // $ nightwatch --safari\n      this.option('safari', {\n        group: 'Browsers',\n        description: 'Run tests in Apple Safari'\n      });\n\n      // $ nightwatch --edge\n      this.option('edge', {\n        group: 'Browsers',\n        description: 'Run tests in Microsoft Edge'\n      });\n      */\n      // $ nightwatch -g\n      // $ nightwatch --group\n      this.option('group', {\n        group: 'Tags & filtering',\n        description: 'Runs a group of tests (i.e. a folder)',\n        alias: 'g'\n      });\n\n      // $ nightwatch -s\n      // $ nightwatch --skipgroup\n      this.option('skipgroup', {\n        group: 'Tags & filtering',\n        description: 'Skips one or several (comma separated) group of tests.',\n        alias: 's'\n      });\n\n      // $ nightwatch -f\n      // $ nightwatch --filter\n      this.option('filter', {\n        group: 'Tags & filtering',\n        description: 'Specify a filter (glob expression) as the file name format to use when loading the files.',\n        alias: 'f'\n      });\n\n      // $ nightwatch -a\n      // $ nightwatch --tag\n      this.option('tag', {\n        group: 'Tags & filtering',\n        description: 'Only run tests with the given tag.',\n        alias: 'a'\n      });\n\n      // $ nightwatch --skiptags\n      this.option('skiptags', {\n        group: 'Tags & filtering',\n        description: 'Skips tests that have the specified tag or tags (comma separated).'\n      });\n\n      // $ nightwatch --grep\n      this.option('grep', {\n        group: 'Test Filters – Mocha only',\n        description: 'Only run tests matching this string or regexp.'\n      });\n\n      // $ nightwatch --fgrep\n      this.option('fgrep', {\n        group: 'Test Filters – Mocha only',\n        description: 'Only run tests containing this string.'\n      });\n\n      // $ nightwatch --invert\n      this.option('invert', {\n        group: 'Test Filters – Mocha only',\n        description: 'Inverts --grep and --fgrep matches.'\n      });\n\n      // $ nightwatch --retries\n      this.option('retries', {\n        group: 'Retrying',\n        description: 'Retries failed or errored testcases up <n> times.'\n      });\n\n      // $ nightwatch --suiteRetries\n      this.option('suiteRetries', {\n        group: 'Retrying',\n        description: 'Retries failed or errored testsuites up <n> times.'\n      });\n\n      // $ nightwatch --timeout\n      this.option('timeout', {\n        description: 'Set the global timeout for assertion retries before an assertion fails.'\n      });\n\n      // $ nightwatch -o\n      // $ nightwatch --output\n      this.option('output', {\n        group: 'Reporting',\n        description: 'Where to save the (JUnit XML) test reports.',\n        alias: 'o'\n      });\n\n      // $ nightwatch -r\n      // $ nightwatch --reporter\n      this.option('reporter', {\n        group: 'Reporting',\n        description: 'Name of a predefined reporter (e.g. junit) or path to a custom reporter file to use.',\n        alias: 'r',\n        defaults: DefaultSettings.default_reporter\n      });\n\n      // $ nightwatch --trace\n      this.option('trace', {\n        group: 'Reporting',\n        descriptions: 'Record trace information during nightwatch execution.'\n      });\n\n      // $ nightwatch --open\n      this.option('open', {\n        group: 'Reporting',\n        description: 'Opens the HTML report generated in the default browser at the end of test run'\n      });\n\n      // $ nightwatch --reuse-browser\n      this.option('reuse-browser', {\n        description: 'Use the same browser session to run the individual test suites'\n      });\n\n      // $ nightwatch --parallel\n      // this.option('parallel', {\n      //   description: 'Enable running the tests in parallel mode, via test workers.'\n      // });\n\n      // $ nightwatch --workers=5\n      this.option('workers', {\n        description: 'Max number of test files running at the same time (default: CPU cores; e.g. workers=4)'\n      });\n\n      // $ nightwatch --sequential\n      this.option('serial', {\n        description: 'Executes tests serially (disables parallel mode)'\n      });\n\n      // $ nightwatch --headless\n      this.option('headless', {\n        description: 'Launch the browser (Chrome, Edge or Firefox) in headless mode.'\n      });\n\n      // $ nightwatch --devtools\n      this.option('devtools', {\n        description: 'Automatically open devtools when launching the browser (Chrome, Edge, or Safari).'\n      });\n\n      // $ nightwatch --debug\n      this.option('debug', {\n        group: 'Component Tests',\n        description: 'Automatically pause the test execution after mounting the component and open the Nightwatch debug REPL interface.'\n      });\n\n      // $ nightwatch --story\n      this.option('story', {\n        group: 'Component Tests',\n        description: 'Allows to specify which story to run from the current file (when using Storybook or JSX written in component story format)'\n      });\n\n      // $ nightwatch --preview\n      this.option('preview', {\n        group: 'Component Tests',\n        description: 'Used to preview a component story/test; automatically pause the test execution after mounting the component.'\n      });\n\n      // $ nightwatch --verbose\n      this.option('verbose', {\n        description: 'Displays extended HTTP command logging during the test run.'\n      });\n\n      // $ nightwatch --fail-fast\n      this.option('fail-fast', {\n        description: 'Run in \"fail-fast\" mode: if a test suite cannot be started, the rest will be aborted'\n      });\n\n      // $ nightwatch -h\n      // $ nightwatch --help\n      this.option('help', {\n        description: 'Shows this help (pass COLORS=0 env variable to disable colors).',\n        group: 'Info & help',\n        alias: 'h'\n      });\n\n      // $ nightwatch --info\n      this.option('info', {\n        description: 'Shows environment info, i.e. OS, cpu, Node.js and installed browsers.',\n        group: 'Info & help'\n      });\n\n      // $ nightwatch -v\n      // $ nightwatch --version\n      this.option('version', {\n        alias: 'v',\n        group: 'Info & help',\n        description: 'Shows version information.'\n      });\n\n      // $ nightwatch --list-files\n      this.option('list-files', {\n        description: 'Shows list of files present in the project.'\n      });\n\n      this.option('deviceId', {\n        description: 'Set the udid of real iOS device'\n      });\n\n      this.option('rerun-failed', {\n        description: 'Rerun failed test suites'\n      });\n\n      return this;\n    }\n  }\n\n  function longest(xs) {\n    return Math.max.apply(null, xs.map(x => x.length));\n  }\n\n  function rebase(base, dir) {\n    const ds = path.normalize(dir).split('/').slice(1);\n    const bs = path.normalize(base).split('/').slice(1);\n\n    for (var i = 0; ds[i] && ds[i] === bs[i]; i++) {\n      ;\n    }\n    ds.splice(0, i);\n    bs.splice(0, i);\n\n    const p = path.normalize(bs.map(function () {\n      return '..';\n    }).concat(ds).join('/')).replace(/\\/$/, '').replace(/^$/, '.');\n\n    return p.match(/^[./]/) ? p : './' + p;\n  }\n\n  let __instance__;\n\n  if (!__instance__) {\n    __instance__ = new ArgvSetup(process.argv.slice(2));\n    __instance__.showUsage(`Usage: ${Logger.colors.cyan('$0 [source] [options]')}`).setup();\n  }\n\n  return __instance__;\n})();\n"
  },
  {
    "path": "lib/runner/cli/cli.js",
    "content": "const path = require('path');\nconst lodashCloneDeep = require('lodash/cloneDeep');\nconst ArgvSetup = require('./argv-setup.js');\nconst Settings = require('../../settings/settings.js');\nconst Globals = require('../../testsuite/globals.js');\nconst Factory = require('../../transport/factory.js');\nconst Concurrency = require('../concurrency');\nconst Utils = require('../../utils');\nconst Runner = require('../runner.js');\nconst ProcessListener = require('../process-listener.js');\nconst analyticsCollector = require('../../utils/analytics.js');\nconst {RealIosDeviceIdError, iosRealDeviceUDID, isRealIos, isMobile, killSimulator, isAndroid} = require('../../utils/mobile.js');\nconst {Logger, singleSourceFile, isSafari, isLocalhost} = Utils;\nconst NightwatchEvent = require('../eventHub.js');\nconst {NightwatchEventHub, DEFAULT_RUNNER_EVENTS} = NightwatchEvent;\nconst {GlobalHook} = DEFAULT_RUNNER_EVENTS;\n\nclass CliRunner {\n  static get CONFIG_FILE_JS() {\n    return './nightwatch.conf.js';\n  }\n\n  static get CONFIG_FILE_CJS() {\n    return './nightwatch.conf.cjs';\n  }\n\n  static get CONFIG_FILE_TS() {\n    return './nightwatch.conf.ts';\n  }\n\n  static createDefaultConfig(destFileName) {\n    // eslint-disable-next-line no-console\n    console.log(Logger.colors.cyan('No config file found in the current working directory, creating nightwatch.conf.js in the current folder...'));\n\n    const templateFile = path.join(__dirname, 'nightwatch.conf.ejs');\n    const os = require('os');\n    const fs = require('fs');\n    const ejs = require('ejs');\n\n    const tplData = fs.readFileSync(templateFile).toString();\n\n    let launch_url = 'https://nightwatchjs.org';\n    const availablePlugins = [];\n    const autoLoadPlugins = [{\n      'vite-plugin-nightwatch': {\n        launch_url: 'http://localhost:3000'\n      }\n    }, {\n      '@nightwatch/storybook': {\n        launch_url: 'http://localhost:6006'\n      }\n    }, {\n      '@nightwatch/react': {}\n    }];\n\n    autoLoadPlugins.forEach(plugin => {\n      try {\n        const pluginName = Object.keys(plugin)[0];\n        const pluginPath = Utils.getPluginPath(pluginName);\n\n        availablePlugins.push(pluginName);\n        if (plugin[pluginName].launch_url) {\n          launch_url = plugin[pluginName].launch_url;\n        }\n      } catch (err) {\n        // plugin is not installed\n      }\n    });\n\n    let rendered = ejs.render(tplData, {\n      plugins: (availablePlugins.length > 0) ? JSON.stringify(availablePlugins) : '[]',\n      launch_url,\n      isMacOS: os.platform() === 'darwin'\n    });\n\n    rendered = Utils.stripControlChars(rendered);\n    try {\n      fs.writeFileSync(destFileName, rendered, {encoding: 'utf-8'});\n\n      return true;\n    } catch (err) {\n      Logger.error(`Failed to save nightwatch.conf.js config file to ${destFileName}. You need to manually create either a nightwatch.json or nightwatch.conf.js configuration file.`);\n      Logger.error(err);\n\n      return false;\n    }\n  }\n\n  constructor(argv = {}) {\n    if (argv.source && !argv._source) {\n      argv._source = argv.source;\n      delete argv.source;\n    }\n\n    if (argv._source && Utils.isString(argv._source)) {\n      argv._source = [argv._source];\n    }\n\n    if (argv.firefox) {\n      argv.e = argv.env = 'firefox';\n    } else if (argv.chrome) {\n      argv.e = argv.env = 'chrome';\n    } else if (argv.safari) {\n      argv.e = argv.env = 'safari';\n    } else if (argv.edge) {\n      argv.e = argv.env = 'edge';\n    }\n\n    this.argv = argv;\n\n    this.testRunner = null;\n    this.globals = null;\n    this.testEnv = null;\n    this.testEnvArray = [];\n\n    if (!argv.disable_process_listener) {\n      this.processListener = new ProcessListener();\n    }\n  }\n\n  initTestSettings(userSettings = {}, baseSettings = null, argv = null, testEnv = '', asyncLoading) {\n    this.test_settings = Settings.parse(userSettings, baseSettings, argv, testEnv);\n\n    this.setMobileOptions(argv);\n    this.setLoggingOptions();\n    this.setupGlobalHooks();\n\n    const result = this.readExternalHooks(asyncLoading);\n\n    if (result instanceof Promise) {\n      return result.then(() => {\n        this.globalsSetup(argv);\n      });\n    }\n\n    this.globalsSetup(argv);\n\n    return this;\n  }\n\n  globalsSetup(argv) {\n    this.globals.init();\n    this.setTimeoutOptions(argv);\n  }\n\n  setTimeoutOptions(argv) {\n    if (argv.timeout) {\n      const timeout = parseInt(argv.timeout, 10);\n      if (!isNaN(timeout)) {\n        this.test_settings.globals.waitForConditionTimeout = timeout;\n        this.test_settings.globals.retryAssertionTimeout = timeout;\n      }\n    }\n  }\n\n  setMobileOptions(argv) {\n    const {desiredCapabilities, selenium = {}} = this.test_settings;\n\n    if (isRealIos(desiredCapabilities) && !selenium.use_appium) {\n      if (argv.deviceId) {\n        this.test_settings.desiredCapabilities['safari:deviceUDID'] = iosRealDeviceUDID(argv.deviceId);\n      } else if (!desiredCapabilities['safari:deviceUDID']) {\n        throw new RealIosDeviceIdError();\n      }\n    }\n\n    if (isAndroid(desiredCapabilities) && argv.deviceId && !selenium.use_appium) {\n      if (desiredCapabilities['goog:chromeOptions']) {\n        this.test_settings.desiredCapabilities['goog:chromeOptions'].androidDeviceSerial = argv.deviceId;\n      } else if (desiredCapabilities['moz:firefoxOptions']) {\n        this.test_settings.desiredCapabilities['moz:firefoxOptions'].androidDeviceSerial = argv.deviceId;\n      }\n    }\n  }\n\n  setupGlobalHooks() {\n    this.globals = new Globals(this.test_settings, this.argv, this.testEnv);\n  }\n\n  readExternalHooks(asyncLoading = true) {\n    return this.globals.readExternal(asyncLoading);\n  }\n\n  /**\n   * backwards compatibility\n   * @readonly\n   * @deprecated\n   * @return {*}\n   */\n  get settings() {\n    return this.baseSettings;\n  }\n\n  setCurrentTestEnv() {\n    this.testEnv = Utils.isString(this.argv.env) ? this.argv.env : Settings.DEFAULT_ENV;\n    this.testEnvArray = this.testEnv.split(',');\n\n    if (!this.baseSettings) {\n      return this;\n    }\n\n    this.availableTestEnvs = Object.keys(this.baseSettings.test_settings).filter(key => {\n      return Utils.isObject(this.baseSettings.test_settings[key]);\n    });\n\n    this.validateTestEnvironments();\n\n    return this;\n  }\n\n  setLoggingOptions() {\n    Logger.setOptions(this.test_settings);\n\n    return this;\n  }\n\n  /**\n   * @param {object} [settings]\n   * @return {CliRunner}\n   */\n  async setupAsync(settings) {\n    this.baseSettings = await this.loadConfig();\n    await this.commonSetup(settings);\n\n    return this;\n  }\n\n  /**\n   * Backwords compatibility for runner\n   * @param {object} [settings]\n   * @return {CliRunner}\n   */\n  setup(settings) {\n    this.baseSettings = this.loadConfig();\n    this.commonSetup(settings, false);\n\n    return this;\n  }\n\n  commonSetup(settings, asyncLoading = true) {\n    this.validateConfig();\n    this.setCurrentTestEnv();\n\n    const result = this.parseTestSettings(settings, asyncLoading);\n    if (asyncLoading) {\n      return result.then(() => this.runnerSetup());\n    }\n\n    this.runnerSetup();\n\n    return this;\n  }\n\n  runnerSetup() {\n    this.createTestRunner();\n    this.setupConcurrency();\n    this.loadTypescriptTranspiler();\n\n    analyticsCollector.updateSettings(this.test_settings);\n    analyticsCollector.updateLogger(Logger);\n\n    analyticsCollector.collectEvent('nw_test_run', {\n      arg_parallel: this.argv.parallel,\n      browser_name: this.test_settings.desiredCapabilities.browserName,\n      test_workers_enabled: this.test_settings.testWorkersEnabled,\n      use_xpath: this.test_settings.use_xpath,\n      is_bstack: this.test_settings.desiredCapabilities['bstack:options'] !== undefined,\n      test_runner: this.test_settings.test_runner ? this.test_settings.test_runner.type : null\n    });\n\n    this.setupEventHub();\n  }\n\n  isRegisterEventHandlersCallbackExistsInGlobal() {\n    const {globals} = this.test_settings;\n    const {plugins = []} = this.globals;\n\n    return Utils.isFunction(globals.registerEventHandlers) || plugins.some(plugin => plugin.globals && Utils.isFunction(plugin.globals.registerEventHandlers));\n  }\n\n  setupEventHub() {\n    if (this.isRegisterEventHandlersCallbackExistsInGlobal() && !NightwatchEventHub.isAvailable) {\n      NightwatchEventHub.runner = this.testRunner.type;\n      NightwatchEventHub.isAvailable = true;\n\n      const {globals, output_folder} = this.test_settings;\n      NightwatchEventHub.output_folder = output_folder;\n      const {plugins} = this.globals;\n\n      if (Utils.isFunction(globals.registerEventHandlers)) {\n        globals.registerEventHandlers(NightwatchEventHub);\n      }\n\n      if (plugins.length > 0) {\n        plugins.forEach((plugin) => {\n          if (plugin.globals && Utils.isFunction(plugin.globals.registerEventHandlers)) {\n            plugin.globals.registerEventHandlers(NightwatchEventHub);\n          }\n        });\n      }\n    }\n  }\n\n  loadTypescriptTranspiler() {\n    const projectTsFilePath = Utils.findTSConfigFile(this.test_settings.tsconfig_path);\n\n    if (projectTsFilePath !== '' && !this.test_settings.disable_typescript) {\n      Utils.loadTSNode(projectTsFilePath);\n    }\n  }\n\n  isConfigDefault(configFile, localJsValue = CliRunner.CONFIG_FILE_JS) {\n    return ArgvSetup.isDefault('config', configFile) || path.resolve(configFile) === localJsValue;\n  }\n\n  getLocalConfigFileName() {\n    let packageInfo;\n    try {\n      packageInfo = require(path.resolve('package.json'));\n    } catch (err) {\n      packageInfo = null;\n    }\n\n    packageInfo = packageInfo || {};\n    const usingESM = packageInfo.type === 'module';\n\n    const usingTS = Utils.fileExistsSync(CliRunner.CONFIG_FILE_TS);\n    if (usingTS) {\n      return path.resolve(CliRunner.CONFIG_FILE_TS);\n    }\n\n    if (usingESM) {\n      return path.resolve(CliRunner.CONFIG_FILE_CJS);\n    }\n\n    return path.resolve(CliRunner.CONFIG_FILE_JS);\n  }\n\n  loadConfig() {\n    if (!this.argv.config) {\n      return null;\n    }\n\n    const localJsOrTsValue = this.getLocalConfigFileName();\n\n    // use default nightwatch.json file if we haven't received another value\n    if (this.isConfigDefault(this.argv.config, localJsOrTsValue)) {\n      let newConfigCreated = false;\n      const defaultValue = ArgvSetup.getDefault('config');\n      const hasJsOrTsConfig = Utils.fileExistsSync(localJsOrTsValue);\n      const hasJsonConfig = Utils.fileExistsSync(defaultValue);\n\n      if (!hasJsOrTsConfig && !hasJsonConfig) {\n        newConfigCreated = CliRunner.createDefaultConfig(localJsOrTsValue);\n      }\n\n      if (hasJsOrTsConfig || newConfigCreated) {\n        this.argv.config = localJsOrTsValue;\n      } else if (hasJsonConfig) {\n        this.argv.config = path.join(path.resolve('./'), this.argv.config);\n      }\n    } else {\n      this.argv.config = path.resolve(this.argv.config);\n    }\n\n    return require(this.argv.config);\n  }\n\n  validateConfig() {\n    // checking if the env passed is valid\n    if (this.baseSettings && !this.baseSettings.test_settings) {\n      this.baseSettings.test_settings = {\n        default: {}\n      };\n    }\n\n    return this;\n  }\n\n  /**\n   * Validates and parses the test settings\n   * @param {object} [settings]\n   * @returns {CliRunner|Promise}\n   */\n  parseTestSettings(settings = {}, asyncLoading = true) {\n    this.userSettings = lodashCloneDeep(settings);\n    const result = this.initTestSettings(settings, this.baseSettings, this.argv, this.testEnv, asyncLoading);\n\n    if (result instanceof Promise) {\n      return result;\n    }\n\n    return this;\n  }\n\n  runGlobalHook(key, args = [], isParallelHook = false) {\n    let promise;\n    const {globals} = this.test_settings;\n\n    if (isParallelHook && Concurrency.isWorker() || !isParallelHook && !Concurrency.isWorker()) {\n      const start_time = new Date();\n\n      if (Utils.isFunction(globals[key])) {\n        NightwatchEventHub.emit(GlobalHook[key].started, {\n          start_time: start_time\n        });\n      }\n\n      promise = this.globals.runGlobalHook(key, args);\n\n      return promise.finally(() => {\n        if (Utils.isFunction(globals[key])) {\n          NightwatchEventHub.emit(GlobalHook[key].finished, {\n            start_time: start_time,\n            end_time: new Date()\n          });\n        }\n      });\n    }\n\n    return Promise.resolve();\n  }\n\n  validateTestEnvironments() {\n    for (let i = 0; i < this.testEnvArray.length; i++) {\n      if (this.testEnvArray[i] === 'default') {\n        continue;\n      }\n      if (!(this.testEnvArray[i] in this.baseSettings.test_settings)) {\n        const error = new Error(`Invalid testing environment specified: ${this.testEnvArray[i]}. \\n\\n ${Logger.colors.light_cyan('Available environments are:')}\\n ${Logger.inspectObject(this.availableTestEnvs)}`);\n        error.showTrace = false;\n        throw error;\n      }\n    }\n\n    return this;\n  }\n\n  ///////////////////////////////////////////////////////////////////////////////////////////////////////////\n  // Concurrency related\n  ///////////////////////////////////////////////////////////////////////////////////////////////////////////\n  get testWorkersMode() {\n    return this.isTestWorkersEnabled() && !this.testRunner.isTestWorker();\n  }\n\n  usingServer(test_settings = {}) {\n    // TODO: selenium_host and seleniumHost are for backwards compatability.\n    // remove these in future versions.\n    return Utils.isObject(test_settings.selenium) || test_settings.selenium_host || test_settings.seleniumHost;\n  }\n\n  isTestWorkersEnabled() {\n    if (this.testRunner.supportsParallelTestSuiteRun === false) {\n      return false;\n    }\n\n    const testWorkers = this.test_settings.testWorkersEnabled && !singleSourceFile(this.argv);\n    if (!testWorkers) {\n\n      if (this.argv.debug) {\n        Logger.info('Disabling parallelism while running in debug mode');\n      }\n\n      return false;\n    }\n\n    for (const env of this.testEnvArray) {\n      const {webdriver = {}} = this.testEnvSettings[env];\n      const desiredCapabilities = this.testEnvSettings[env].capabilities || this.testEnvSettings[env].desiredCapabilities;\n\n      if (isMobile(desiredCapabilities) && !this.usingServer(this.testEnvSettings[env])) {\n\n        if (Concurrency.isWorker()) {\n          Logger.info('Disabling parallelism while running tests on mobile platform');\n        }\n\n        return false;\n      }\n\n      if (isSafari(desiredCapabilities) && isLocalhost(webdriver)) {\n        this.isSafariEnvPresent = true;\n        if (Concurrency.isMasterProcess()) {\n          // eslint-disable-next-line no-console\n          console.warn('Running tests in parallel is not supported in Safari. Tests will run in serial mode.');\n        }\n\n        return false;\n      }\n    }\n\n\n    return true;\n  }\n\n  parallelMode() {\n    return this.testEnvArray.length > 1 || this.testWorkersMode;\n  }\n\n  setupConcurrency() {\n\n    if (this.testRunner?.type === Runner.MOCHA_RUNNER) {\n      this.test_settings.use_child_process = true;\n    }\n\n    this.concurrency = new Concurrency(this.test_settings, this.argv, this.isTestWorkersEnabled());\n\n    return this;\n  }\n\n  isConcurrencyEnabled() {\n    return this.testRunner.supportsConcurrency && this.parallelMode();\n  }\n\n  ///////////////////////////////////////////////////////////////////////////////////////////////////////////\n  // Test runner related\n  ///////////////////////////////////////////////////////////////////////////////////////////////////////////\n\n  executeTestRunner(modules) {\n    return this.testRunner.run(modules);\n  }\n\n  createTestRunner() {\n    this.testRunner = Runner.create(this.test_settings, this.argv, {\n      globalHooks: this.globals ? this.globals.hooks : null,\n      globalsInstance: this.globals\n    });\n\n    if (this.processListener) {\n      this.processListener.setTestRunner(this.testRunner);\n    }\n\n    return this;\n  }\n\n  get testEnvSettings() {\n    if (this.__testEnvSettings) {\n      return this.__testEnvSettings;\n    }\n    this.__testEnvSettings = {};\n    for (const env of this.testEnvArray) {\n      this.__testEnvSettings[env] = Settings.parse(this.userSettings, this.baseSettings, this.argv, env);\n    }\n\n    return this.__testEnvSettings;\n  }\n\n  async getTestsFiles() {\n    const modules = {};\n    for (const env of this.testEnvArray) {\n      modules[env] = await Runner.readTestSource(this.testEnvSettings[env], this.argv);\n    }\n\n    return modules;\n  }\n\n  /**\n   *\n   * @param [done]\n   * @return {*}\n   */\n  runTests(done = null) {\n    return this.runGlobalHook('before', [this.test_settings, this.testEnvSettings])\n      .then(_ => {\n        return this.runGlobalHook('beforeChildProcess', [this.test_settings], true);\n      })\n      .then(_ => {\n        return this.getTestsFiles();\n      })\n      .then(modules => {\n        if (!this.testRunner) {\n          const error = new Error(`Test runner '${this.test_settings.test_runner.type}' is not known.`);\n          error.showTrace = false;\n          error.detailedErr = `\\n Verify \"test_runner\" settings: \\n  ${Logger.inspectObject(this.test_settings.test_runner)}`;\n\n          throw error;\n        }\n\n        let promise = Promise.resolve();\n\n        if (this.test_settings.selenium && this.test_settings.selenium.start_process) {\n          promise = Factory.createSeleniumService(this);\n        }\n\n        const {real_mobile, avd} = this.test_settings.desiredCapabilities;\n        if (!real_mobile && avd) {\n          const AndroidServer = require('../androidEmulator.js');\n          this.androidServer = new AndroidServer(avd);\n\n          promise = promise.then(() => this.androidServer.launchEmulator());\n        }\n\n        return promise.then(() => {\n          if (this.isConcurrencyEnabled()) {\n            return this.testRunner.runConcurrent(this.testEnvArray, modules, this.isTestWorkersEnabled(), this.isSafariEnvPresent)\n              .then(exitCode => {\n                if (exitCode > 0) {\n                  this.processListener.setExitCode(exitCode);\n                }\n              });\n          }\n\n          return this.executeTestRunner(modules[this.testEnv]);\n        });\n      })\n      .catch(err => {\n        if (err.detailedErr) {\n          err.data = err.detailedErr;\n        }\n\n        if (!err.sessionCreate && !err.displayed) {\n          Logger.error(err);\n\n          if (err.data) {\n            Logger.warn(' ' + err.data);\n          }\n\n          // eslint-disable-next-line no-console\n          console.log('');\n        }\n\n        err.displayed = true;\n\n        return err;\n      })\n      .then(errorOrFailed => {\n        if (this.seleniumService) {\n          // stop the Selenium Server if running\n          const {service} = this.seleniumService;\n          if (service && service.kill) {\n            // Give the selenium server some time to close down its browser drivers\n            return new Promise((resolve, reject) => {\n              setTimeout(() => {\n                service.kill()\n                  .catch(err => {\n                    Logger.error(err);\n                  })\n                  .then(() => this.seleniumService.stop())\n                  .then(() => resolve());\n              }, 100);\n            }).then(() => {\n              return errorOrFailed;\n            });\n          }\n        }\n\n        return errorOrFailed;\n      })\n      .then(errorOrFailed => {\n        if (errorOrFailed instanceof Error || errorOrFailed === true) {\n          try {\n            this.processListener.setExitCode(5);\n          } catch (e) {\n            // eslint-disable-next-line no-console\n            console.error(e);\n          }\n        }\n\n        return this.runGlobalHook('afterChildProcess', [], true)\n          .then(_ => {\n            return this.runGlobalHook('after');\n          })\n          .then(result => {\n            return errorOrFailed;\n          });\n      })\n      .catch(err => {\n        // eslint-disable-next-line no-console\n        console.log('');\n\n        try {\n          this.processListener.setExitCode(5);\n        } catch (e) {\n          // eslint-disable-next-line no-console\n          console.error(e);\n        }\n\n        return err;\n      })\n      .then(errorOrFailed => {\n        if (typeof done == 'function' && !Concurrency.isWorker()) {\n          if (errorOrFailed instanceof Error) {\n            return done(errorOrFailed);\n          }\n\n          return done();\n        }\n\n        if (errorOrFailed instanceof Error) {\n          throw errorOrFailed;\n        }\n\n        if (this.androidServer && !this.androidServer.emulatorAlreadyRunning) {\n          this.androidServer.killEmulator();\n        }\n\n        if (this.test_settings.deviceUDID && !isRealIos(this.test_settings.desiredCapabilities)) {\n          killSimulator(this.test_settings.deviceUDID);\n        }\n\n        analyticsCollector.__flush();\n\n        return errorOrFailed;\n      });\n  }\n}\n\nmodule.exports = CliRunner;\n"
  },
  {
    "path": "lib/runner/cli/nightwatch.conf.ejs",
    "content": "//\n// Refer to the online docs for more details:\n// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html\n//\n//  _   _  _         _      _                     _          _\n// | \\ | |(_)       | |    | |                   | |        | |\n// |  \\| | _   __ _ | |__  | |_ __      __  __ _ | |_   ___ | |__\n// | . ` || | / _` || '_ \\ | __|\\ \\ /\\ / / / _` || __| / __|| '_ \\\n// | |\\  || || (_| || | | || |_  \\ V  V / | (_| || |_ | (__ | | | |\n// \\_| \\_/|_| \\__, ||_| |_| \\__|  \\_/\\_/   \\__,_| \\__| \\___||_| |_|\n//             __/ |\n//            |___/\n//\n\nmodule.exports = {\n  // An array of folders (excluding subfolders) where your tests are located;\n  // if this is not specified, the test source must be passed as the second argument to the test runner.\n  src_folders: [],\n\n  // See https://nightwatchjs.org/guide/concepts/page-object-model.html\n  page_objects_path: ['node_modules/nightwatch/examples/pages/'],\n\n  // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html\n  custom_commands_path: ['node_modules/nightwatch/examples/custom-commands/'],\n\n  // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html\n  custom_assertions_path: '',\n\n  // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html\n  <% if (plugins) { %>plugins: <%- plugins %>,\n  <% } %>\n  // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals\n  globals_path : '',\n\n  // Set this to true to disable bounding boxes on terminal output. Useful when running in some CI environments.\n  disable_output_boxes: false,\n\n  webdriver: {},\n\n  test_workers: {\n    enabled: true,\n    workers: 'auto'\n  },\n\n  test_settings: {\n    default: {\n      disable_error_log: false,\n      launch_url: '<%- launch_url %>',\n\n      screenshots: {\n        enabled: false,\n        path: 'screens',\n        on_failure: true\n      },\n\n      desiredCapabilities: {\n        browserName : 'firefox'\n      },\n\n      webdriver: {\n        start_process: true,\n        server_path: ''\n      }\n    },\n\n    <% if (isMacOS) { %>safari: {\n      desiredCapabilities : {\n        browserName : 'safari',\n        alwaysMatch: {\n          acceptInsecureCerts: false\n        }\n      },\n      webdriver: {\n        start_process: true,\n        server_path: ''\n      }\n    },<% } %>\n\n    firefox: {\n      desiredCapabilities : {\n        browserName : 'firefox',\n        acceptInsecureCerts: true,\n        'moz:firefoxOptions': {\n          args: [\n            // '-headless',\n            // '-verbose'\n          ]\n        }\n      },\n      webdriver: {\n        start_process: true,\n        server_path: '',\n        cli_args: [\n          // very verbose geckodriver logs\n          // '-vv'\n        ]\n      }\n    },\n\n    chrome: {\n      desiredCapabilities : {\n        browserName : 'chrome',\n        'goog:chromeOptions' : {\n          // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/\n          //\n          // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)\n          w3c: true,\n          args: [\n            //'--no-sandbox',\n            //'--ignore-certificate-errors',\n            //'--allow-insecure-localhost',\n            //'--headless'\n          ]\n        }\n      },\n\n      webdriver: {\n        start_process: true,\n        server_path: '',\n        cli_args: [\n          // '--verbose'\n        ]\n      }\n    },\n\n    edge: {\n      desiredCapabilities : {\n        browserName : 'MicrosoftEdge',\n        'ms:edgeOptions' : {\n          w3c: true,\n          // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options\n          args: [\n            //'--headless'\n          ]\n        }\n      },\n\n      webdriver: {\n        start_process: true,\n        // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/\n        //  and set the location below:\n        server_path: '',\n        cli_args: [\n          // '--verbose'\n        ]\n      }\n    },\n\n    //////////////////////////////////////////////////////////////////////////////////\n    // Configuration for when using cucumber-js (https://cucumber.io)                |\n    //                                                                               |\n    // It uses the bundled examples inside the nightwatch examples folder; feel free |\n    // to adapt this to your own project needs                                       |\n    //////////////////////////////////////////////////////////////////////////////////\n    'cucumber-js': {\n      src_folders: ['examples/cucumber-js/features/step_definitions'],\n\n      test_runner: {\n        // set cucumber as the runner\n        type: 'cucumber',\n\n        // define cucumber specific options\n        options: {\n          //set the feature path\n          feature_path: 'node_modules/nightwatch/examples/cucumber-js/*/*.feature',\n\n          // start the webdriver session automatically (enabled by default)\n          // auto_start_session: true\n\n          // use parallel execution in Cucumber\n          // workers: 2 // set number of workers to use (can also be defined in the cli as --workers=2\n        }\n      }\n    },\n\n    //////////////////////////////////////////////////////////////////////////////////\n    // Configuration for when using the browserstack.com cloud service               |\n    //                                                                               |\n    // Please set the username and access key by setting the environment variables:  |\n    // - BROWSERSTACK_USERNAME                                                       |\n    // - BROWSERSTACK_ACCESS_KEY                                                     |\n    // .env files are supported                                                      |\n    //////////////////////////////////////////////////////////////////////////////////\n    browserstack: {\n      selenium: {\n        host: 'hub.browserstack.com',\n        port: 443\n      },\n      // More info on configuring capabilities can be found on:\n      // https://www.browserstack.com/automate/capabilities?tag=selenium-4\n      desiredCapabilities: {\n        'bstack:options' : {\n          userName: '${BROWSERSTACK_USERNAME}',\n          accessKey: '${BROWSERSTACK_ACCESS_KEY}',\n        }\n      },\n\n      disable_error_log: true,\n      webdriver: {\n        timeout_options: {\n          timeout: 60000,\n          retry_attempts: 3\n        },\n        keep_alive: true,\n        start_process: false\n      }\n    },\n\n    'browserstack.local': {\n      extends: 'browserstack',\n      desiredCapabilities: {\n        'browserstack.local': true\n      }\n    },\n\n    'browserstack.chrome': {\n      extends: 'browserstack',\n      desiredCapabilities: {\n        browserName: 'chrome',\n        chromeOptions : {\n          w3c: true\n        }\n      }\n    },\n\n    'browserstack.firefox': {\n      extends: 'browserstack',\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    },\n\n    'browserstack.ie': {\n      extends: 'browserstack',\n      desiredCapabilities: {\n        browserName: 'internet explorer',\n        browserVersion: '11.0'\n      }\n    },\n\n    'browserstack.safari': {\n      extends: 'browserstack',\n      desiredCapabilities: {\n        browserName: 'safari'\n      }\n    },\n\n    'browserstack.local_chrome': {\n      extends: 'browserstack.local',\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    },\n\n    'browserstack.local_firefox': {\n      extends: 'browserstack.local',\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    },\n    //////////////////////////////////////////////////////////////////////////////////\n    // Configuration for when using the SauceLabs cloud service                      |\n    //                                                                               |\n    // Please set the username and access key by setting the environment variables:  |\n    // - SAUCE_USERNAME                                                              |\n    // - SAUCE_ACCESS_KEY                                                            |\n    //////////////////////////////////////////////////////////////////////////////////\n    saucelabs: {\n      selenium: {\n        host: 'ondemand.saucelabs.com',\n        port: 443\n      },\n      // More info on configuring capabilities can be found on:\n      // https://docs.saucelabs.com/dev/test-configuration-options/\n      desiredCapabilities: {\n        'sauce:options' : {\n          username: '${SAUCE_USERNAME}',\n          accessKey: '${SAUCE_ACCESS_KEY}',\n          screenResolution: '1280x1024'\n          // https://docs.saucelabs.com/dev/cli/sauce-connect-proxy/#--region\n          // region: 'us-west-1'\n          // https://docs.saucelabs.com/dev/test-configuration-options/#tunnelidentifier\n          // parentTunnel: '',\n          // tunnelIdentifier: '',\n        }\n      },\n      disable_error_log: false,\n      webdriver: {\n        start_process: false\n      }\n    },\n    'saucelabs.chrome': {\n      extends: 'saucelabs',\n      desiredCapabilities: {\n        browserName: 'chrome',\n        browserVersion: 'latest',\n        javascriptEnabled: true,\n        acceptSslCerts: true,\n        timeZone: 'London',\n        chromeOptions : {\n          w3c: true\n        }\n      }\n    },\n    'saucelabs.firefox': {\n      extends: 'saucelabs',\n      desiredCapabilities: {\n        browserName: 'firefox',\n        browserVersion: 'latest',\n        javascriptEnabled: true,\n        acceptSslCerts: true,\n        timeZone: 'London'\n      }\n    },\n    //////////////////////////////////////////////////////////////////////////////////\n    // Configuration for when using the Selenium service, either locally or remote,  |\n    //  like Selenium Grid                                                           |\n    //////////////////////////////////////////////////////////////////////////////////\n    selenium_server: {\n      // Selenium Server is running locally and is managed by Nightwatch\n      // Install the NPM package @nightwatch/selenium-server or download the selenium server jar file from https://github.com/SeleniumHQ/selenium/releases/, e.g.: selenium-server-4.1.1.jar\n      selenium: {\n        start_process: true,\n        port: 4444,\n        server_path: '', // Leave empty if @nightwatch/selenium-server is installed\n        command: 'standalone', // Selenium 4 only\n        cli_args: {\n          //'webdriver.gecko.driver': '',\n          //'webdriver.chrome.driver': ''\n        }\n      },\n      webdriver: {\n        start_process: false,\n        default_path_prefix: '/wd/hub'\n      }\n    },\n\n    'selenium.chrome': {\n      extends: 'selenium_server',\n      desiredCapabilities: {\n        browserName: 'chrome',\n        chromeOptions : {\n          w3c: true\n        }\n      }\n    },\n\n    'selenium.firefox': {\n      extends: 'selenium_server',\n      desiredCapabilities: {\n        browserName: 'firefox',\n        'moz:firefoxOptions': {\n          args: [\n            // '-headless',\n            // '-verbose'\n          ]\n        }\n      }\n    }\n  }\n};\n"
  },
  {
    "path": "lib/runner/concurrency/child-process.js",
    "content": "const child_process = require('child_process');\nconst EventEmitter = require('events');\nconst boxen = require('boxen');\nconst {Logger, isObject, symbols} = require('../../utils');\nconst ProcessListener = require('../../runner/process-listener.js');\n\nlet prevIndex = 0;\n\nclass ChildProcess extends EventEmitter {\n  static get defaultStartDelay() {\n    return 10;\n  }\n\n  static get prevIndex() {\n    return prevIndex;\n  }\n\n  static set prevIndex(val) {\n    prevIndex = val;\n  }\n\n  constructor(environment, index, env_output, settings, args) {\n    super();\n\n    this.settings = settings;\n    this.env_output = env_output || [];\n    this.mainModule = process.mainModule.filename;\n    this.index = index;\n    this.itemKey = this.getChildProcessEnvKey(environment);\n    this.startDelay = settings.parallel_process_delay || ChildProcess.defaultStartDelay;\n    this.environment = environment;\n    this.child = null;\n    this.globalExitCode = 0;\n    this.env_label = '';\n    this.args = args || [];\n  }\n\n  setLabel(label) {\n    this.env_itemKey = label;\n    this.env_label = this.settings.disable_colors ? ` ${label} ` : Logger.colors.bgBlack.yellow.bold(` ${label} `);\n\n    return this;\n  }\n\n  printLog(msg) {\n    if (this.settings.output) {\n      // eslint-disable-next-line no-console\n      console.info(msg);\n    }\n  }\n\n  getChildProcessEnvKey(env) {\n    return `${env}_${this.index + 1}`;\n  }\n\n  /**\n   * Returns an array of cli arguments to be passed to the child process,\n   * based on the args passed to the main process\n   * @returns {Array}\n   */\n  getArgs() {\n    const args = [];\n\n    if (isObject(this.settings.test_workers)) {\n      const {node_options} = this.settings.test_workers;\n      if (node_options === 'auto' || node_options === 'inherit' || node_options === true) {\n        args.push.apply(args, process.execArgv);\n      } else if (Array.isArray(node_options)) {\n        args.push.apply(args, node_options);\n      }\n    }\n\n    args.push(this.mainModule);\n    args.push.apply(args, this.args);\n    args.push('--parallel-mode');\n\n    return args;\n  }\n\n\n  writeToStdout(data) {\n    data = data.toString().trim();\n\n    const color_pair = this.availColors[this.index % 4];\n    let output = '';\n\n    if (ChildProcess.prevIndex !== this.index) {\n      ChildProcess.prevIndex = this.index;\n      if (this.settings.live_output) {\n        output += '\\n';\n      }\n    }\n\n    if (this.settings.output && (this.settings.detailed_output || !this.settings.silent)) {\n      let childProcessLabel;\n      if (this.settings.disable_colors) {\n        childProcessLabel = ' ' + this.environment + ' ';\n      } else {\n        childProcessLabel = '';\n        this.env_label = Logger.colors[color_pair[0]][color_pair[1]](` ${this.environment} `);\n      }\n\n      const lines = data.split('\\n').map(line => {\n        return childProcessLabel + ' ' + line + ' ';\n      });\n\n      data = lines.join('\\n');\n    }\n\n    output += data;\n\n    if (this.settings.live_output) {\n      process.stdout.write(output + '\\n');\n    } else {\n      this.env_output.push(output);\n    }\n  }\n\n  run(colors, type) {\n    this.availColors = colors;\n\n    const cliArgs = this.getArgs();\n    const env = {};\n\n    Object.keys(process.env).forEach(function(key) {\n      env[key] = process.env[key];\n    });\n\n    return new Promise((resolve, reject) => {\n      setTimeout(() => {\n        env.__NIGHTWATCH_PARALLEL_MODE = '1';\n        env.__NIGHTWATCH_ENV = this.environment;\n        env.__NIGHTWATCH_ENV_KEY = this.itemKey;\n        env.__NIGHTWATCH_ENV_LABEL = this.env_itemKey;\n        env.__NIGHTWATCH_PARALLEL_TYPE = type;\n\n        this.child = child_process.spawn(process.execPath, cliArgs, {\n          cwd: process.cwd(),\n          encoding: 'utf8',\n          env,\n          stdio: [null, null, null, 'ipc']\n        });\n\n        if (typeof this.child.send == 'function') {\n          this.child.send(JSON.stringify({\n            type: 'vite',\n            vite_port: this.settings.vite_port\n          }));\n        }\n\n        const color_pair = this.availColors[this.index % 4];\n\n        this.printLog(' Running: ' + Logger.colors[color_pair[0]][color_pair[1]](` ${this.env_itemKey} `));\n\n        this.child.stdout.on('data', data => {\n          this.writeToStdout(data);\n        });\n\n        this.child.on('message', message => {\n          this.emit('message', message);\n        });\n\n        this.child.stderr.on('data', data => {\n          this.writeToStdout(data);\n        });\n\n        this.processListener = new ProcessListener(this.child);\n\n        this.child.on('exit', code => {\n          this.printLog('');\n\n          const status = code > 0 ? symbols.fail : symbols.ok;\n\n          if (this.settings.disable_output_boxes) {\n            // eslint-disable-next-line no-console\n            console.log(`\\n${status} ${this.env_label}`, this.env_output.join('\\n'), '\\n');\n          } else {\n            // eslint-disable-next-line no-console\n            console.log(boxen(this.env_output.join('\\n'), {title: `────────────────── ${status} ${this.env_label}`, padding: 1, borderColor: 'cyan'}));\n          }\n\n          code = code || this.processListener.exitCode;\n          resolve(code);\n        });\n\n\n      }, this.index * this.startDelay);\n    });\n  }\n}\n\nmodule.exports = ChildProcess;\n"
  },
  {
    "path": "lib/runner/concurrency/index.js",
    "content": "const EventEmitter = require('events');\nconst Utils = require('../../utils');\nconst {isObject, isNumber} = Utils;\nconst lodashCloneDeep = require('lodash/cloneDeep');\nconst ChildProcess = require('./child-process.js');\nconst WorkerPool = require('./worker-process.js');\nconst {Logger} = Utils;\n\nclass Concurrency extends EventEmitter {\n  constructor(settings = {}, argv = {}, isTestWorkerEnabled, isSafariEnvPresent = false) {\n    super();\n\n    this.argv = argv;\n    this.settings = lodashCloneDeep(settings);\n    this.useChildProcess = settings.use_child_process;\n    this.childProcessOutput = {};\n    this.globalExitCode = 0;\n    this.testWorkersEnabled = typeof isTestWorkerEnabled !== 'undefined' ? isTestWorkerEnabled : settings.testWorkersEnabled;\n    this.isSafariEnvPresent = isSafariEnvPresent;\n  }\n\n  static getChildProcessArgs(envs) {\n    const childProcessArgs = [];\n    let arg;\n\n    for (let i = 2; i < process.argv.length; i++) {\n      arg = process.argv[i];\n      if (arg === '-e' || arg === '--env') {\n        i++;\n      } else if (!(arg.startsWith('--env=') || arg.startsWith('--e='))) {\n        childProcessArgs.push(arg);\n      }\n    }\n\n    return childProcessArgs;\n  }\n\n\n  /**\n   *\n   * @param {String} label\n   * @param {Array} args\n   * @param {Array} extraArgs\n   * @param {Number} index\n   * @return {ChildProcess}\n   */\n  createChildProcess(label, args = [], extraArgs = [], index = 0) {\n    this.childProcessOutput[label] = [];\n    const childArgs = args.slice().concat(extraArgs);\n\n    const childProcess = new ChildProcess(label, index, this.childProcessOutput[label], this.settings, childArgs);\n    childProcess.on('message', data => {\n      this.emit('message', data);\n    });\n\n    return childProcess;\n  }\n\n  /**\n   *\n   * @param {ChildProcess} childProcess\n   * @param {String} outputLabel\n   * @param {Array} availColors\n   * @param {String} type\n   * @return {Promise}\n   */\n  runChildProcess(childProcess, outputLabel, availColors, type) {\n    return childProcess.setLabel(outputLabel)\n      .run(availColors, type)\n      .then(exitCode => {\n        if (exitCode > 0) {\n          this.globalExitCode = exitCode;\n        }\n      });\n  }\n\n\n  /**\n   *\n   * @param {Array} envs\n   * @param {Array} [modules]\n   * @return {Promise}\n   */\n  runChildProcesses(envs, modules) {\n    const availColors = Concurrency.getAvailableColors();\n    const args = Concurrency.getChildProcessArgs(envs);\n\n    if (this.testWorkersEnabled) {\n      const jobs = [];\n      if (envs.length > 0) {\n        envs.forEach((env) => {\n          const envModules = modules[env];\n          const jobList = envModules.map((module) => {\n            return {\n              env,\n              module\n            };\n          });\n          jobs.push(...jobList);\n        });\n      } else {\n        const jobList = modules.map((module) => {\n          return {\n            module\n          };\n        });\n        jobs.push(...jobList);\n      }\n\n      return this.runMultipleTestProcess(jobs, args, availColors);\n    }\n\n    return this.runProcessTestEnvironment(envs, args, availColors);\n  }\n\n  /**\n   *\n   * @param {Array} envs\n   * @param {Array} modules\n   */\n  runMultiple(envs = [], modules) {\n    if (this.useChildProcess) {\n      return this.runChildProcesses(envs, modules)\n        .then(_ => {\n          return this.globalExitCode;\n        });\n    }\n\n    return this.runWorkerProcesses(envs, modules)\n      .catch(_ => {\n        this.globalExitCode = 1;\n      })\n      .then(_ => {\n        return this.globalExitCode;\n      });\n  }\n\n  /**\n   *\n   * @param {Array} envs\n   * @param {Array} [modules]\n   * @return {Promise}\n   */\n  runWorkerProcesses(envs, modules) {\n    const availColors = Concurrency.getAvailableColors();\n\n    if (this.testWorkersEnabled) {\n      const jobs = [];\n      if (envs.length > 0) {\n        envs.forEach((env) => {\n          const envModules = modules[env];\n          const jobList = envModules.map((module) => {\n            return {\n              env,\n              module\n            };\n          });\n          jobs.push(...jobList);\n        });\n      } else {\n        const jobList = modules.map((module) => {\n          return {\n            module\n          };\n        });\n        jobs.push(...jobList);\n      }\n\n      return this.runMultipleTestWorkers(jobs, availColors);\n    }\n\n    return this.runWorkerTestEnvironments(envs, availColors);\n  }\n\n  /**\n   *\n   * @param {Array} envs\n   * @param {Array} args\n   * @param {Array} availColors\n   * @return {Promise}\n   */\n  runProcessTestEnvironment(envs, args, availColors) {\n    return Promise.all(envs.map((environment, index) => {\n      const extraArgs = ['--env', environment];\n      if (this.isSafariEnvPresent) {\n        extraArgs.push('--serial');\n      }\n      const childProcess = this.createChildProcess(environment, args, extraArgs, index);\n\n      return this.runChildProcess(childProcess, environment + ' environment', availColors, 'envs');\n    }));\n  }\n\n  /**\n   *\n   * @param {Array} envs\n   * @param {Array} availColors\n   * @return {Promise}\n   */\n  runWorkerTestEnvironments(envs, availColors) {\n\n    let maxWorkerCount = this.getTestWorkersCount();\n    const remaining = envs.length;\n\n    maxWorkerCount = Math.min(maxWorkerCount, remaining);\n    const workerPool = this.setupWorkerPool(['--parallel-mode'], this.settings, maxWorkerCount);\n\n    envs.forEach((env) => {\n      const workerArgv = {...this.argv};\n      workerArgv.env = workerArgv.e = env;\n      workerPool.addTask({\n        argv: workerArgv,\n        settings: this.settings,\n        label: `${env} environment`,\n        colors: availColors\n      });\n    });\n\n    return new Promise((resolve, reject) => {\n      Promise.allSettled(workerPool.tasks)\n        .then(values => {\n          values.some(({status}) =>  status === 'rejected') ? reject() : resolve();\n        });\n    });\n  }\n\n  /**\n  *\n  * @param {Array} modules\n  * @param {Array} args\n  * @param {Array} availColors\n  */\n  runMultipleTestProcess(modules, args, availColors) {\n    let maxWorkerCount = this.getTestWorkersCount();\n    let remaining = modules.length;\n\n    maxWorkerCount = Math.min(maxWorkerCount, remaining);\n\n    if (this.settings.output) {\n      Logger.info(`Launching up to ${maxWorkerCount} concurrent test worker processes...\\n`);\n    }\n\n\n    return new Promise((resolve, reject) => {\n      Concurrency.buildProcessQueue(maxWorkerCount, modules, (env, modulePath, index, next) => {\n        let outputLabel = Utils.getModuleKey(modulePath, this.settings.src_folders, modules);\n        const flags = ['--test', modulePath, '--test-worker'];\n\n        if (env) {\n          flags.unshift('--env', env);\n          outputLabel = `${env}: ${outputLabel}`;\n        }\n\n        const childProcess = this.createChildProcess(outputLabel, args, flags, index);\n\n        return this.runChildProcess(childProcess, outputLabel, availColors, 'workers')\n          .then(_ => {\n            remaining -= 1;\n\n            if (remaining > 0) {\n              next();\n            } else {\n              resolve();\n            }\n          });\n      });\n    });\n\n  }\n  /**\n   *\n   * @param {Array} modules\n   * @param {Array} availColors\n   */\n  runMultipleTestWorkers(modules, availColors) {\n    let maxWorkerCount = this.getTestWorkersCount();\n    const remaining = modules.length;\n\n    maxWorkerCount = Math.min(maxWorkerCount, remaining);\n\n    if (this.settings.output) {\n      Logger.info(`Launching up to ${maxWorkerCount} concurrent test worker processes...\\n`);\n    }\n\n    const workerPool = this.setupWorkerPool(['--test-worker', '--parallel-mode'], this.settings, maxWorkerCount);\n\n    modules.forEach(({module, env}) => {\n      let outputLabel = Utils.getModuleKey(module, this.settings.src_folders, modules);\n      outputLabel = env ? `${env}: ${outputLabel}` : outputLabel;\n\n      const workerArgv = {...this.argv};\n      workerArgv._source = [module];\n      workerArgv.env = env;\n      workerArgv['test-worker'] = true;\n\n      return workerPool.addTask({\n        argv: workerArgv,\n        settings: this.settings,\n        label: outputLabel,\n        colors: availColors\n      });\n    });\n\n\n    return new Promise((resolve, reject) => {\n      Promise.allSettled(workerPool.tasks)\n        .then(values => {\n          values.some(({status}) =>  status === 'rejected') ? reject() : resolve();\n        });\n    });\n  }\n\n\n  /**\n   *\n   * @param {Array} args\n   * @param {Object} settings\n   * @param {Number} maxWorkerCount\n   */\n  setupWorkerPool(args, settings, maxWorkerCount) {\n    const workerPool = new WorkerPool(args, settings, maxWorkerCount);\n    workerPool.on('message', data => {\n      this.emit('message', data);\n    });\n\n    return workerPool;\n  }\n\n  /**\n   * @param {String} [label]\n   */\n  printChildProcessOutput(label) {\n    if (label) {\n      this.childProcessOutput[label] = this.childProcessOutput[label].filter(item => {\n        return item !== '';\n      }).map(item => {\n        if (item === '\\\\n') {\n          item = '\\n';\n        }\n\n        return item;\n      });\n\n      this.childProcessOutput[label].forEach(function(output) {\n        process.stdout.write(output + '\\n');\n      });\n      this.childProcessOutput[label] = [];\n\n      return;\n    }\n\n    Object.keys(this.childProcessOutput).forEach(environment => {\n      this.printChildProcessOutput(environment);\n    });\n  }\n\n  /**\n   * @return {number}\n   */\n  getTestWorkersCount() {\n    const {test_workers} = this.settings;\n    let workers = require('os').cpus().length;\n\n    if (isObject(test_workers) && isNumber(test_workers.workers)) {\n      workers = test_workers.workers;\n    }\n\n    return workers;\n  }\n\n  /**\n   * @param {number} concurrency\n   * @param {Array} modules\n   * @param {function} fn\n   */\n  static buildProcessQueue(maxWorkers, modules, fn) {\n    const queue = modules.slice(0);\n\n    let workers = 0;\n    let index = 0;\n\n    const next = function() {\n      workers -= 1;\n      process();\n    };\n\n    const process = function(done = function() {}) {\n      while (workers < maxWorkers) {\n        workers += 1;\n\n        if (queue.length) {\n          const item = queue.shift();\n          fn(item.env, item.module, index++, next);\n        } else {\n          done();\n        }\n      }\n    };\n\n    process();\n  }\n\n  static getAvailableColors() {\n    const availColorPairs = [\n      ['bgRed', 'white'],\n      ['bgGreen', 'black'],\n      ['bgBlue', 'white'],\n      ['bgMagenta', 'white']\n    ];\n    let currentIndex = availColorPairs.length;\n    let temporaryValue;\n    let randomIndex;\n\n    // While there remain elements to shuffle...\n    while (0 !== currentIndex) {\n      randomIndex = Math.floor(Math.random() * currentIndex);\n      currentIndex -= 1;\n\n      // And swap it with the current element.\n      temporaryValue = availColorPairs[currentIndex];\n      availColorPairs[currentIndex] = availColorPairs[randomIndex];\n      availColorPairs[randomIndex] = temporaryValue;\n    }\n\n    return availColorPairs;\n  }\n\n  static isWorker() {\n    return process.env.__NIGHTWATCH_PARALLEL_MODE === '1' || WorkerPool.isWorkerThread;\n  }\n\n  static isTestWorker(argv = {}) {\n    return Concurrency.isWorker() && argv['test-worker'];\n  }\n\n  static isMasterProcess() {\n    return !Concurrency.isWorker();\n  }\n}\n\nmodule.exports = Concurrency;\n"
  },
  {
    "path": "lib/runner/concurrency/task.js",
    "content": "const Nightwatch = require('../../index');\nfunction runWorkerTask({argv, port1}) {\n  const writeData = (data) => {\n    data = data.toString().trim();\n\n    if (data){\n      port1.postMessage({\n        type: 'stdout',\n        data: data\n      });\n    }\n  };\n\n  process.stdout.write = writeData;\n  process.stderr.write = writeData;\n\n  //send reports to main thread using message port\n  process.port = port1;\n\n  return Nightwatch.runTests(argv, {});\n}\n\nmodule.exports = runWorkerTask;\n"
  },
  {
    "path": "lib/runner/concurrency/worker-process.js",
    "content": "const path = require('path');\nconst Piscina = require('piscina');\nconst {isWorkerThread} = Piscina;\nconst EventEmitter = require('events');\nconst WorkerTask = require('./worker-task.js');\n\nconst WORKER_FILE = path.resolve(__dirname, 'task.js');\n\nclass WorkerPool extends EventEmitter {\n\n\n  static get isWorkerThread() {\n    return isWorkerThread;\n  }\n\n  get tasks() {\n    return this.__tasks;\n  }\n\n  set tasks(tasks) {\n    this.__tasks = tasks;\n  }\n\n  constructor(args, settings, maxWorkerCount) {\n    super();\n\n    this.settings = settings;\n    this.piscina = new Piscina({\n      filename: WORKER_FILE,\n      maxThreads: maxWorkerCount,\n      argv: args,\n      env: {\n        ...process.env,\n        __NIGHTWATCH_PARALLEL_MODE: '1'\n      }\n    });\n\n    this.__tasks = [];\n    this.index = 0;\n  }\n\n  /**\n   * adds a task to running worker queue\n   */\n  addTask({label, argv, colors} = {}) {\n    const workerTask = new WorkerTask({piscina: this.piscina, index: this.index, label, argv, settings: this.settings});\n\n    workerTask.on('message', (data) => {\n      this.emit('message', data);\n    });\n\n    this.index++;\n    this.__tasks.push(workerTask.runWorkerTask(colors));\n\n  }\n}\n\nmodule.exports = WorkerPool;\n"
  },
  {
    "path": "lib/runner/concurrency/worker-task.js",
    "content": "const boxen = require('boxen');\nconst {MessageChannel} = require('worker_threads');\nconst {Logger, symbols} = require('../../utils');\nconst EventEmitter = require('events');\nconst {isString} = require('../../utils');\n\nlet prevIndex = 0;\n\nclass WorkerTask extends EventEmitter {\n\n  static get prevIndex() {\n    return prevIndex;\n  }\n\n  static set prevIndex(val) {\n    prevIndex = val;\n  }\n\n  constructor({piscina, index, label, settings, argv, task_ouput}) {\n    super();\n\n    this.task_output = task_ouput || [];\n    this.startDelay = settings.parallel_process_delay;\n    this.piscina = piscina;\n    this.label = label;\n    this.settings = settings;\n    this.argv = argv;\n    this.index = index;\n    this.task_label = '';\n    this.env_label = argv.env;\n  }\n\n  printLog(msg) {\n    if (this.settings.output) {\n      // eslint-disable-next-line no-console\n      console.info(msg);\n    }\n  }\n\n  setlabel(colorPair) {\n    this.task_label = this.settings.disable_colors ? ` ${this.label} ` :  Logger.colors[colorPair[0]][colorPair[1]](` ${this.label} `);\n  }\n\n  writeToStdOut(data) {\n    let output = '';\n\n    if (WorkerTask.prevIndex !== this.index) {\n      WorkerTask.prevIndex = this.index;\n      if (this.settings.live_output) {\n        output += '\\n';\n      }\n    }\n\n    if (this.settings.output && (this.settings.detailed_ouput || !this.settings.silent)) {\n      const lines = data.split('\\n').map(line => this.env_label + ' ' + line + ' ');\n      data = lines.join('\\n');\n    }\n\n    output += data;\n\n    if (this.settings.live_output) {\n      process.stdout.write(output + '\\n');\n    } else {\n      this.task_output.push(output);\n    }\n  }\n\n  async runWorkerTask(colors, type) {\n    this.availColors = colors;\n    const colorPair = this.availColors[this.index % 4];\n    this.setlabel(colorPair);\n\n    this.printLog('Running ' + Logger.colors[colorPair[0]][colorPair[1]](` ${this.task_label} `));\n\n    const {port1, port2} = new MessageChannel();\n    port2.onmessage = ({data: result}) => {\n      if (isString(result)) {\n        try {\n          result = JSON.parse(result);\n          // eslint-disable-next-line no-empty\n        } catch (e) {}\n      }\n\n      switch (result.type) {\n        case 'testsuite_finished':\n          result.itemKey = this.label,\n          this.emit('message', result);\n          break;\n\n        case 'stdout':\n          this.writeToStdOut(result.data);\n          break;\n      }\n    };\n    port2.unref();\n\n    return new Promise((resolve, reject) => {\n      setTimeout(() => {\n        this.piscina.run({argv: this.argv, port1}, {transferList: [port1]})\n          .catch(err => err)\n          .then(failures => {\n            if (this.settings.disable_output_boxes){\n            // eslint-disable-next-line no-console\n              console.log(`${failures ? symbols.fail : symbols.ok} ${this.task_label}\\n`, this.task_output.join('\\n'), '\\n');\n            } else {\n            // eslint-disable-next-line no-console\n              console.log(boxen(this.task_output.join('\\n'), {title: `────────────────── ${failures ? symbols.fail : symbols.ok} ${this.task_label}`, padding: 1, borderColor: 'cyan'}));\n            }\n\n            //throw error to mark exit-code of the process\n            if (failures) {\n              return reject(new Error());\n            }\n            resolve();\n          });\n      }, this.index * this.startDelay);\n    });\n  }\n}\n\nmodule.exports = WorkerTask;\n"
  },
  {
    "path": "lib/runner/eventHub.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst EventEmitter = require('events');\nconst {Logger, createFolder} = require('../utils');\n\nclass NightwatchEventHub extends EventEmitter {\n  emit(eventName, data) {\n    if (this.isAvailable) {\n      try {\n        super.emit(eventName, data);\n      } catch (err) {\n        Logger.error(err);\n      }\n    }\n\n    if (eventName === 'TestFinished' && this.output_folder && this.runner === 'cucumber') {\n      let {output_folder} = this;\n      output_folder = path.join(output_folder, 'cucumber');\n      const filename = path.join(output_folder, 'cucumber-report.json');\n\n      this.writeReportFile(filename, JSON.stringify(data.report, null, 2), true, output_folder)\n        .then(_ => {\n          Logger.info(Logger.colors.stack_trace(`Wrote JSON report file to: ${path.resolve(filename)}`));\n        });\n    }\n  }\n\n  get isAvailable() {\n    return this.eventFnExist;\n  }\n\n  set isAvailable(eventFnExist) {\n    this.eventFnExist = eventFnExist;\n  }\n\n  set runner(type) {\n    this.runnerType = type;\n  }\n\n  get runner() {\n    return this.runnerType;\n  }\n\n  writeReportFile(filename, rendered, shouldCreateFolder, output_folder) {\n    return (shouldCreateFolder ? createFolder(output_folder) : Promise.resolve())\n      .then(() => {\n        return new Promise((resolve, reject) => {\n          fs.writeFile(filename, rendered, function(err) {\n            if (err) {\n              return reject(err);\n            }\n\n            resolve();\n          });\n        });\n      });\n  }\n}\n\nconst instance = new NightwatchEventHub();\n\nmodule.exports = {\n  NightwatchEventHub: instance,\n  COMMON_EVENTS: {\n    ScreenshotCreated: 'ScreenshotCreated'\n  },\n  DEFAULT_RUNNER_EVENTS: {\n    GlobalHook: {\n      before: {\n        started: 'GlobalBeforeStarted',\n        finished: 'GlobalBeforeFinished'\n      },\n  \n      beforeChildProcess: {\n        started: 'GlobalBeforeChildProcessStarted',\n        finished: 'GlobalBeforeChildProcessFinished'\n      },\n  \n      beforeEach: {\n        started: 'GlobalBeforeEachStarted',\n        finished: 'GlobalBeforeEachFinished'\n      },\n  \n      afterEach: {\n        started: 'GlobalAfterEachStarted',\n        finished: 'GlobalAfterEachFinished'\n      },\n  \n      afterChildProcess: {\n        started: 'GlobalAfterChildProcessStarted',\n        finished: 'GlobalAfterChildProcessFinished'\n      },\n  \n      after: {\n        started: 'GlobalAfterStarted',\n        finished: 'GlobalAfterFinished'\n      }\n    },\n\n    TestSuiteHook: {\n      started: 'TestSuiteStarted',\n      finished: 'TestSuiteFinished',\n      \n      before: {\n        started: 'BeforeStarted',\n        finished: 'BeforeFinished'\n      },\n\n      beforeEach: {\n        started: 'BeforeEachStarted',\n        finished: 'BeforeEachFinished'\n      },\n\n      test: {\n        started: 'TestRunStarted',\n        finished: 'TestRunFinished'\n      },\n  \n      afterEach: {\n        started: 'AfterEachStarted',\n        finished: 'AfterEachFinished'\n      },\n\n      after: {\n        started: 'AfterStarted',\n        finished: 'AfterFinished'\n      }\n    },\n\n    LogCreated: 'LogCreated'\n  },\n  CUCUMBER_RUNNER_EVENTS: {\n    TestStarted: 'TestStarted',\n    TestFinished: 'TestFinished',\n    TestCaseStarted: 'TestCaseStarted',\n    TestCaseFinished: 'TestCaseFinished',\n    TestStepStarted: 'TestStepStarted',\n    TestStepFinished: 'TestStepFinished'\n  }\n};\n"
  },
  {
    "path": "lib/runner/folder-walk.js",
    "content": "const path = require('path');\nconst minimatch = require('minimatch');\nconst lodashCloneDeep = require('lodash/cloneDeep');\nconst Utils = require('../utils');\nconst FilenameMatcher = require('./matchers/filename.js');\nconst TagsMatcher = require('./matchers/tags.js');\n\nclass Results {\n  constructor() {\n    this.dataArray = [];\n  }\n\n  getData() {\n    return this.dataArray;\n  }\n\n  register(sourcePath) {\n    if (!Array.isArray(sourcePath)) {\n      sourcePath = [sourcePath];\n    }\n\n    sourcePath.filter(item => {\n      return Utils.isFileNameValid(item);\n    }).forEach(item => {\n      if (this.dataArray.indexOf(item) === -1) {\n        this.dataArray.push(item);\n      }\n    });\n  }\n}\n\nclass Walker {\n  constructor(testSource = [], settings, argv = {}) {\n    if (Utils.isString(testSource)) {\n      testSource = [testSource];\n    }\n\n    this.testSource = testSource;\n    this.settings = lodashCloneDeep(settings);\n    this.argv = argv;\n    this.usingMocha = this.settings.test_runner && this.settings.test_runner.type === 'mocha';\n    this.usingCucumber = this.settings.test_runner?.type === 'cucumber';\n\n    this.registerMatchers();\n\n    this.results = new Results();\n    if (!this.argv['launch-url']) {\n      this.validateSource();\n    }\n  }\n\n  get promise() {\n    return this.__promise;\n  }\n\n  get disableTs() {\n    return this.settings.disable_typescript === true;\n  }\n\n  isComponentTestingMode() {\n    return this.settings.globals.component_tests_mode;\n  }\n\n  validateSource() {\n    if (this.testSource.length === 0) {\n      const err = new Error('No test source specified, please check \"src_folders\" config');\n\n      err.showTrace = false;\n\n      if (Array.isArray(this.settings.src_folders) && this.settings.src_folders.length > 0) {\n        const srcFolders = this.settings.src_folders.map(item => `\"${item}\"`).join(', ');\n        err.message += `; src_folders: ${srcFolders}`;\n      }\n\n      if (this.argv.group) {\n        const groups = this.argv.group.map(item => `\"${item}\"`).join(', ');\n        err.message += `; group(s): ${groups}`;\n      }\n\n      err.detailedErr = 'Run nightwatch with --help to display usage info.';\n      err.message += '.';\n\n      throw err;\n    }\n  }\n\n  registerMatchers() {\n    const {settings, argv} = this;\n    this.tags = new TagsMatcher(settings);\n\n    if (settings.exclude) {\n      FilenameMatcher.addMatcher(FilenameMatcher.TYPE_EXCLUDE, {settings, argv});\n    }\n\n    if (settings.filter) {\n      FilenameMatcher.addMatcher(FilenameMatcher.TYPE_FILTER, {settings, argv});\n    }\n  }\n\n  /**\n   * Apply filters on resolved file names\n   *\n   * @param {Array} list\n   */\n  applyFilters(list) {\n    if (this.usingCucumber) {\n      return list;\n    }\n\n    return list.sort().filter(filePath => {\n      let matched = true;\n\n      if (this.settings.filter && !FilenameMatcher.register.filter.match(filePath)) {\n        matched = false;\n      }\n\n      if (this.settings.exclude && FilenameMatcher.register.exclude.match(filePath)) {\n        matched = false;\n      }\n\n      const filename = filePath.split(path.sep).slice(-1)[0];\n\n      if (this.settings.filename_filter) {\n        matched = matched && minimatch(filename, this.settings.filename_filter);\n      }\n\n      return matched;\n    });\n  }\n\n  async applyTagFilter(list) {\n    if (!Array.isArray(list)) {\n      return;\n    }\n\n    if (!this.tags.anyTagsDefined() || this.usingCucumber) {\n      return list;\n    }\n\n    const matches = await Promise.all(list.map(filePath => {\n      return this.tags.loadModule(filePath);\n    }));\n\n    return matches.filter(context => {\n      if (!context) {\n        return false;\n      }\n\n      return this.tags.checkModuleTags(context);\n    }).map(context => context.modulePath);\n  }\n\n  promiseFn(resolve, reject) {\n    const sourcePath = this.modulePathsCopy.shift();\n    let fullPath = path.resolve(sourcePath);\n\n    Utils.checkPath(fullPath)\n      .catch(err => {\n        if (err.code === 'ENOENT') {\n          if (sourcePath.startsWith('examples/')) {\n            // try the examples folder\n            fullPath = path.join(__dirname, '../../', sourcePath);\n          } else {\n            fullPath = path.join(Utils.getConfigFolder(this.argv), sourcePath);\n          }\n\n          return Utils.checkPath(fullPath, err);\n        }\n\n        throw err;\n      })\n      .then(stat => {\n        if (stat && stat.isFile()) {\n          return fullPath;\n        }\n\n        if (stat && !stat.isDirectory()) {\n          return null;\n        }\n\n        return this.readFolderDeep(fullPath);\n      })\n      .then(fullPath => {\n        if (fullPath && Utils.isString(fullPath)) {\n          fullPath = [fullPath];\n        }\n\n        if (Array.isArray(fullPath)) {\n          return this.applyFilters(fullPath);\n        }\n      })\n      .then(fullPath => {\n        return this.applyTagFilter(fullPath);\n      })\n      .then(fullPath => {\n        if (fullPath) {\n          this.results.register(fullPath);\n        }\n\n        if (this.modulePathsCopy.length === 0) {\n          resolve(this.results.getData());\n        } else {\n          this.promiseFn(resolve, reject);\n        }\n      })\n      .catch(function(err) {\n        reject(err);\n      });\n  }\n\n  createPromise() {\n    this.__promise = new Promise(this.promiseFn.bind(this));\n\n    return this;\n  }\n\n  readTestSource() {\n    this.modulePathsCopy = this.testSource.slice(0);\n\n    this.createPromise();\n\n    return this.promise;\n  }\n\n  readFolderDeep(folderPath) {\n    return Utils.readDir(folderPath)\n      .then(list => {\n        if (list.length === 0) {\n          return null;\n        }\n\n        const statPromises = list.map(resource => {\n          resource = path.isAbsolute(resource) ? resource : path.join(folderPath, resource);\n\n          return Utils.checkPath(resource);\n        });\n\n        return Promise.all(statPromises)\n          .then(statResults => {\n            return statResults.reduce((prev, value, index) => {\n              prev.push([list[index], value]);\n\n              return prev;\n            }, []);\n          });\n      })\n      .then(promiseResults => {\n        if (!promiseResults) {\n          return null;\n        }\n\n        return Promise.all(promiseResults.map(item => {\n          let resource = item[0];\n          const stat = item[1];\n\n          if (path.isAbsolute(resource)) {\n            folderPath = path.dirname(resource);\n            resource = path.basename(resource);\n          }\n\n          if (stat && stat.isDirectory()) {\n            const dirName = path.basename(resource);\n            const isExcluded = FilenameMatcher.isFolderExcluded(resource, this.settings); // prevent loading of files from an excluded folder\n            const isSkipped = this.settings.skipgroup && this.settings.skipgroup.indexOf(dirName) > -1;\n\n            if (isExcluded || isSkipped) {\n              return null;\n            }\n\n            return this.readFolderDeep(path.join(folderPath, resource));\n          }\n\n          if (this.disableTs && Utils.isTsFile(resource)) {\n            return null;\n          }\n\n          if (stat && stat.isFile() && Utils.isFileNameValid(resource)) {\n            return path.join(folderPath, resource);\n          }\n\n          return null;\n        }));\n      }).then(results => {\n        if (!results) {\n          return null;\n        }\n\n        return Utils.flattenArrayDeep(results, 3);\n      });\n  }\n}\n\nmodule.exports = Walker;\n"
  },
  {
    "path": "lib/runner/matchers/filename.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst minimatch = require('minimatch');\n\nconst MatchRegister = {\n  exclude: {},\n  filter: {}\n};\n\nclass MatcherExclude {\n  constructor({pattern, settings, argv}) {\n    this.src_folders = settings.src_folders || [];\n    this.argv = argv;\n    this.filterPattern = this.adaptFilterPattern(pattern);\n  }\n\n  adaptFilterPattern(pattern) {\n    if (!Array.isArray(pattern)) {\n      pattern = [pattern];\n    }\n\n    return pattern.map(item => {\n      const pathResolved = path.resolve(item);\n      let srcFolder;\n\n      if (this.src_folders.length === 1) {\n        // in case there is only one src_folder, check if the pattern is specified\n        // relative to the src_folder\n        srcFolder = this.src_folders[0];\n      } else if (this.src_folders.length === 0 && Array.isArray(this.argv._source) && (this.argv._source.length > 0)) {\n        srcFolder = this.argv._source[0];\n      }\n\n      if (srcFolder) {\n        srcFolder = path.resolve(srcFolder);\n\n        if (pathResolved.startsWith(srcFolder)) {\n          return pathResolved;\n        }\n\n        return path.join(srcFolder, item);\n      }\n\n      return pathResolved;\n    });\n  }\n\n  match(fullPath) {\n    return this.filterPattern.some(pattern => fullPath.includes(pattern) || minimatch(fullPath, pattern));\n  }\n}\n\nclass FilenameMatcher {\n  static get TYPE_EXCLUDE() {\n    return 'exclude';\n  }\n\n  static get TYPE_FILTER() {\n    return 'filter';\n  }\n\n  static create({type, pattern, settings, argv}) {\n    switch (type) {\n      case FilenameMatcher.TYPE_EXCLUDE:\n      case FilenameMatcher.TYPE_FILTER:\n        return new MatcherExclude({pattern, settings, argv});\n    }\n  }\n\n  static isFolderExcluded(resource, opts) {\n    if (!opts.exclude) {\n      return false;\n    }\n\n    return MatchRegister.exclude.filterPattern.some(function(item) {\n      if (item.indexOf(resource) === -1) {\n        return false;\n      }\n\n      try {\n        // FIXME: make this async\n        return fs.statSync(item).isDirectory(); // eslint-disable-next-line no-empty\n      } catch (err) {}\n\n      return false;\n    });\n\n  }\n\n  static addMatcher(type, {settings, argv}) {\n    MatchRegister[type] = FilenameMatcher.create({type, pattern: settings[type], argv, settings});\n  }\n\n  /**\n   * @return {*}\n   */\n  static get register() {\n    return MatchRegister;\n  }\n}\n\nmodule.exports = FilenameMatcher;\n"
  },
  {
    "path": "lib/runner/matchers/tags.js",
    "content": "const Utils = require('../../utils');\nconst {Context} = require('../../testsuite');\nconst {Logger} = Utils;\n\nclass TagsMatcher {\n  static get SEPARATOR() {\n    return ',';\n  }\n\n  constructor(settings) {\n    this.settings = settings;\n    this.tagsToIncludeArrays = TagsMatcher.convertFilterTags(settings.tag_filter);\n    this.tagsToSkipArray = TagsMatcher.convertTags(settings.skiptags);\n    this.usingMocha = this.settings.test_runner && this.settings.test_runner.type === 'mocha';\n  }\n\n  /**\n   * @param {string} testFilePath - file path of a test\n   * @returns {boolean} true if specified test matches given tag\n   */\n  async match(testFilePath) {\n    let context;\n    try {\n      context = await this.loadModule(testFilePath);\n    } catch (e) {\n      Logger.error(e);\n\n      return false;\n    }\n\n    if (!context) {\n      return false;\n    }\n\n    if (context.isDisabled()) {\n      return false;\n    }\n\n    return this.checkModuleTags(context);\n  }\n\n  async loadModule(modulePath) {\n    const {settings} = this;\n\n    const context = new Context({modulePath, settings});\n    context.setReloadModuleCache();\n\n    // Defining global browser object to make it available before nightwatch client created.\n    // To avoid errors like browser is not defined if testsuits has tags\n    Object.defineProperty(global, 'browser', {\n      configurable: true,\n      get: function() {\n        return {};\n      }\n    });\n\n    try {\n      if (this.usingMocha) {\n        context.loadTags({usingMocha: true});\n      } else {\n        await context.init();\n      }\n    } catch (e) {\n      Logger.error(e);\n\n      return false;\n    }\n\n    if (context.isDisabled()) {\n      return false;\n    }\n\n    return context;\n  }\n\n  /**\n   * Verify if the current module contains or does not contain specific tags\n   * @returns {boolean}\n   */\n  checkModuleTags(context) {\n    const tags = context.getTags();\n    const moduleTags = TagsMatcher.convertTags(tags);\n\n    // if we passed the --tag argument, check if the module contains the tag (or tags)\n    if (this.hasIncludeTagFilter() && !this.matchesIncludeTagFilter(moduleTags)) {\n      return false;\n    }\n\n    // if we passed the --skiptags argument, check if the module doesn't contain any of the tags in the skiptags array\n    if (this.hasSkipTagFilter() && !excludesAllTags(moduleTags, this.tagsToSkipArray)) {\n      return false;\n    }\n\n    return true;\n  }\n\n  matchesIncludeTagFilter(moduleTags) {\n    return this.tagsToIncludeArrays.some(tagsArray => containsAllTags(moduleTags, tagsArray));\n  }\n\n  /**\n   * @returns {boolean}\n   */\n  hasIncludeTagFilter() {\n    return this.tagsToIncludeArrays.length > 0;\n  }\n\n  /**\n   * @returns {boolean}\n   */\n  hasSkipTagFilter() {\n    return this.tagsToSkipArray.length > 0;\n  }\n\n  /**\n   * @returns {boolean}\n   */\n  anyTagsDefined() {\n    return this.hasIncludeTagFilter() || this.hasSkipTagFilter();\n  }\n\n  /**\n   * @param {String|Number|Array} tags\n   * @return {Array}\n   */\n  static convertTags(tags) {\n    let tagsArray = Array.isArray(tags) ? tags : [];\n\n    if (Utils.isString(tags) && tags.length > 0) {\n      tagsArray = tags.split(TagsMatcher.SEPARATOR);\n    } else if (Utils.isNumber(tags)) {\n      tagsArray.push(tags);\n    }\n\n    // convert individual tags to strings\n    return tagsArray.map(tag => String(tag).toLowerCase());\n  }\n\n  /**\n   * @param {Array|String} tags\n   * @returns {*}\n   */\n  static convertFilterTags(tags) {\n    if (!tags) {\n      return [];\n    }\n\n    // when multiple --tag arguments are passed (e.g.: --tag a --tag b)\n    //  the resulting array is [a, b], otherwise it is [a]\n    const tagsArray = Array.isArray(tags) ? tags : [tags];\n\n    // now parse each --tag argument\n    return tagsArray.map(t => TagsMatcher.convertTags(t));\n  }\n}\n\n/**\n * Whether a given list of tags contains one particular tag\n *\n * @param {Array} moduleTags\n * @param {String} testTag\n * @returns {boolean}\n */\nconst containsTag = function(moduleTags, testTag) {\n  return moduleTags.includes(testTag);\n};\n\n/**\n * Whether a given list of tags does not contain one particular tag\n *\n * @param {Array} moduleTags\n * @param {String} testTag\n * @returns {boolean}\n */\nconst excludesSingleTag = function(moduleTags, testTag) {\n  return !containsTag(moduleTags, testTag);\n};\n\n/**\n * Whether a given list of tags does not contain any tags in another list\n *\n * @param {Array} moduleTags\n * @param {Array} tagsArray\n * @returns {boolean}\n */\nconst excludesAllTags = function(moduleTags, tagsArray) {\n  return moduleTags.every(testTag => excludesSingleTag(tagsArray, testTag));\n};\n\n/**\n * Whether a given list of tags contains aall tags in another list\n *\n * @param {Array} moduleTags\n * @param {Array} tagsArray\n * @returns {boolean}\n */\nconst containsAllTags = function(moduleTags, tagsArray) {\n  return tagsArray.every(testTag => containsTag(moduleTags, testTag));\n};\n\nmodule.exports = TagsMatcher;\n"
  },
  {
    "path": "lib/runner/process-listener.js",
    "content": "const {Logger} = require('../utils');\nconst analyticsCollector = require('../utils/analytics.js');\n\nmodule.exports = class {\n\n  constructor(proc = process) {\n    this.__exitCode = 0;\n    this.testRunner = null;\n    this.process = proc;\n    this.finishCallback = null;\n\n    this.addExitListener();\n    this.process.once('uncaughtException', err => {\n      this.uncaught(err);\n    });\n\n    this.process.on('unhandledRejection', this.unhandled.bind(this));\n  }\n\n  addExitListener() {\n    // when used programmatically, nightwatch will keep adding exit listeners for each test suite\n    const listeners = this.process.listeners('exit');\n    const isAlreadyAdded = listeners.find(item => {\n      return item.name.includes('exitHandlerNightwatch');\n    });\n\n    if (!isAlreadyAdded) {\n      this.exitHandler = function exitHandlerNightwatch(code) {\n        return this.onExit(code);\n      }.bind(this);\n      this.process.on('exit', this.exitHandler);\n    }\n  }\n\n  setTestRunner(testRunner) {\n    this.testRunner = testRunner;\n\n    return this;\n  }\n\n  setExitCode(code) {\n    this.__exitCode = code;\n\n    return this;\n  }\n\n  get exitCode() {\n    return this.__exitCode;\n  }\n\n  onExit(code) {\n    this.process.exitCode = code || this.exitCode;\n  }\n\n  unhandled(err) {\n    this.uncaught(err, {type: 'unhandledRejection'});\n  }\n\n  getCurrentPromise(err) {\n    if (this.testRunner) {\n      const {currentSuite} = this.testRunner;\n\n      if (currentSuite && (currentSuite.uncaughtError instanceof Error)) {\n        Logger.error('An additional uncaught error occurred while trying to handle the previous one – ' + err.stack);\n\n        return;\n      }\n\n      this.testRunner.registerUncaughtErr(err);\n      if (currentSuite) {\n        currentSuite.emptyQueue();\n        currentSuite.setUncaughtError(err);\n      }\n\n      if (this.testRunner.publishReport) {\n        this.testRunner.publishReport = false;\n        this.testRunner.reportResults().then(() => {}).catch(err => console.error(err));\n      }\n    }\n  }\n\n  uncaught(err, {type = 'uncaughtException'} = {}) {\n    Logger.setOutputEnabled(true); // force log for uncaught exception\n    Logger.enable();\n\n    Logger.error(`${type}: ${err.message}\\n${err.stack}`);\n    analyticsCollector.collectErrorEvent(err, true);\n\n    if (['TimeoutError', 'NoSuchElementError'].includes(err.name) && this.testRunner.type !== 'cucumber') {\n      this.closeProcess(err);\n      if (this.testRunner && this.testRunner.publishReport) {\n        this.testRunner.publishReport = false;\n        this.testRunner.reportResults().catch(() => {}).then(function() {});\n      }\n\n      return;\n    }\n\n    this.getCurrentPromise(err);\n\n    return this.closeProcess(err);\n  }\n\n  closeProcess(err) {\n    if (this.finishCallback) {\n      this.finishCallback(err);\n    }\n\n    this.setExitCode(1).exit();\n  }\n\n  exit() {\n    this.process.exit && this.process.exit(this.exitCode);\n\n    return this;\n  }\n};\n"
  },
  {
    "path": "lib/runner/rerunUtil.js",
    "content": "const {fileExistsSync, Logger} = require('../utils');\nconst path = require('path');\n\nfunction getRerunFailedFile(minimal_report_file_path) {\n  const jsonFile = path.resolve(process.env.NIGHTWATCH_RERUN_REPORT_FILE || minimal_report_file_path || '');\n\n  if (!fileExistsSync(jsonFile)) {\n    const err = new Error('Unable to find the Json reporter file to rerun failed tests');\n\n    err.showTrace = false;\n    err.detailedErr = 'Configure the environment variable NIGHTWATCH_RERUN_REPORT_FILE with Json reporter file path';\n    err.help = [\n      `Try setting ${Logger.colors.cyan('minimal_report_file_path: \"JSON-REPORTER-PATH\"')} in nightwatch configuration`,\n      `Or, try running: ${Logger.colors.cyan('export NIGHTWATCH_RERUN_REPORT_FILE=\"JSON-REPORTER-PATH\"')}`\n    ];\n\n    throw err;\n  }\n\n  return jsonFile;\n}\n\nfunction getTestSourceForRerunFailed(settings) {\n  const {reporter_options: {minimal_report_file_path}} = settings;\n  const minimalJsonFile = getRerunFailedFile(minimal_report_file_path);\n\n  try {\n    const {modules = {}} = require(minimalJsonFile);\n    const testsource = [];\n  \n    Object.keys(modules).forEach(moduleKey => {\n      if (modules[moduleKey] && modules[moduleKey].status === 'fail') {\n        testsource.push(modules[moduleKey].modulePath);\n      }\n    });\n\n    if (testsource.length === 0) {\n      const err = new Error('Rerun Failed Tests: No failed tests found to rerun.');\n      err.noFailedTestFound = true;\n      err.showTrace = false;\n      err.detailedErr = 'Run nightwatch with --help to display usage info.';\n\n      throw err;\n    }\n\n    return testsource;\n  } catch (err) {\n    if (err.noFailedTestFound) {\n      err.message = 'Rerun Failed Tests: Invalid Json reporter.';\n\n      err.showTrace = false;\n      err.detailedErr = 'Please set env variable NIGHTWATCH_RERUN_REPORT_FILE with valid Json reporter path.';\n    }\n\n    throw err;\n  }\n}\n\nmodule.exports = {\n  getRerunFailedFile,\n  getTestSourceForRerunFailed\n};\n"
  },
  {
    "path": "lib/runner/runner.js",
    "content": "const TestSource = require('./test-source.js');\nconst Walker = require('./folder-walk.js');\n\nclass Runner {\n  static get NIGHTWATCH_RUNNER() {\n    return 'nightwatch';\n  }\n\n  static get DEFAULT_RUNNER() {\n    return 'default';\n  }\n\n  static get MOCHA_RUNNER() {\n    return 'mocha';\n  }\n\n  static get CUCUMBER_RUNNER() {\n    return 'cucumber';\n  }\n\n  static createError(err) {\n    if (err) {\n      switch (err.code) {\n        case 'ENOENT': {\n          const error = new Error('An error occurred while trying to start the test runner:');\n          error.detailedErr = `[${err.code}] Cannot read source: ${err.syscall} ${err.path}.`;\n          error.showTrace = false;\n          error.displayed = false;\n\n          throw error;\n        }\n      }\n\n      return err;\n    }\n\n    return false;\n  }\n\n  static checkTestSource(modules, testSource, settings) {\n    // TODO: refactor this into TestSource\n    if (modules && modules.length === 0) {\n      let errorMessage = ['No tests defined! using source folder:', testSource];\n      let err = new Error(errorMessage.join(' '));\n      let detailed = [];\n\n      if (settings.tag_filter && settings.tag_filter.length) {\n        detailed.push(`- using tags filter: ${settings.tag_filter}`);\n      }\n\n      if (settings.skiptags && settings.skiptags.length) {\n        detailed.push(`- using skiptags filter: ${settings.skiptags}`);\n      }\n\n      if (settings.filter) {\n        detailed.push(`- using path filter: ${settings.filter}`);\n      }\n\n      if (settings.exclude) {\n        detailed.push(`- using exclude match: ${settings.exclude}`);\n      }\n\n      if (detailed.length) {\n        err.detailedErr = detailed.join('\\n');\n      }\n\n      return err;\n    }\n\n    return true;\n  }\n\n  static getTestSource(settings, argv = {}) {\n    const testSource = new TestSource(settings, argv);\n\n    return new Walker(testSource.getSource(), settings, argv);\n  }\n\n  static readTestSource(settings, argv = {}) {\n    const walker = Runner.getTestSource(settings, argv);\n\n    if (argv['launch-url']) {\n      return Promise.resolve([]);\n    }\n\n    return walker.readTestSource()\n      .catch(err => {\n        throw Runner.createError(err);\n      })\n      .then(modules => {\n        let error = Runner.checkTestSource(modules, walker.testSource, settings);\n        if (error instanceof Error) {\n          throw error;\n        }\n\n        return modules;\n      });\n  }\n\n  static create(settings, argv, addtOpts) {\n    if (argv.mocha) {\n      settings.test_runner = settings.test_runner || {};\n      settings.test_runner.type = 'mocha';\n    }\n\n    switch (settings.test_runner.type) {\n      case Runner.NIGHTWATCH_RUNNER:\n      case Runner.DEFAULT_RUNNER: {\n        const DefaultRunner = require('./test-runners/default.js');\n\n        return new DefaultRunner(settings, argv, addtOpts);\n      }\n\n      case Runner.MOCHA_RUNNER: {\n        const MochaRunner = require('./test-runners/mocha.js');\n\n        return new MochaRunner(settings, argv, addtOpts);\n      }\n\n      case Runner.CUCUMBER_RUNNER: {\n        const CucumberRunner =  require('./test-runners/cucumber');\n\n        return new CucumberRunner(settings, argv, addtOpts);\n      }\n    }\n  }\n}\n\nmodule.exports = Runner;\n"
  },
  {
    "path": "lib/runner/test-runners/cucumber/README.md",
    "content": "# Using Cucumber.js with Nightwatch 2\n\nNightwatch 2 brings integrated support for using [Cucumber.js](https://cucumber.io/) directly as an alternative test runner. No other plugins are necessary, other than the [Cucumber library](https://www.npmjs.com/package/@cucumber/cucumber) itself (version 7.3 or higher). \n\nSimply run the following in the same project where Nightwatch is also installed:\n\n```sh\n$ npm i @cucumber/cucumber --save-dev\n```\n\nThe [examples folder](https://github.com/nightwatchjs/nightwatch/tree/v2/examples/cucumber-js) contains a few example spec files and cucumber features, as well as configuration details. \n"
  },
  {
    "path": "lib/runner/test-runners/cucumber/_setup_cucumber_runner.js",
    "content": "const Nightwatch = require('../../../index.js');\nconst {Before, After, setDefaultTimeout} = require('@cucumber/cucumber');\n\nsetDefaultTimeout(-1);\n\nBefore(function({pickle, testCaseStartedId}) {\n  const webdriver = {};\n\n  process.env.CUCUMBER_TEST_CASE_STARTED_ID = testCaseStartedId;\n\n  if (this.parameters['webdriver-host']) {\n    webdriver.host = this.parameters['webdriver-host'];\n  }\n\n  if (this.parameters['webdriver-port']) {\n    webdriver.port = this.parameters['webdriver-port'];\n  }\n\n  if (typeof this.parameters['start-process'] != 'undefined') {\n    webdriver.start_process = this.parameters['start-process'];\n  }\n\n  let persist_globals;\n  if (this.parameters['persist-globals']) {\n    persist_globals = this.parameters['persist-globals'];\n  }\n\n  const globals = {};\n  if (this.parameters['retry-interval']) {\n    globals.waitForConditionPollInterval = this.parameters['retry-interval'];\n  }\n\n  this.client = Nightwatch.createClient({\n    headless: this.parameters.headless,\n    env: this.parameters.env,\n    timeout: this.parameters.timeout,\n    parallel: !!this.parameters.parallel,\n    output: !this.parameters['disable-output'],\n    enable_global_apis: true,\n    silent: !this.parameters.verbose,\n    always_async_commands: true,\n    webdriver,\n    persist_globals,\n    config: this.parameters.config,\n    test_settings: this.parameters.settings,\n    globals\n  });\n\n  if (this.client.settings.sync_test_names) {\n    const {name} = pickle;\n    this.client.updateCapabilities({\n      name\n    });\n  }\n\n  // eslint-disable-next-line\n  console.log('\\n');\n\n  const {options = {}} = this.client.settings.test_runner;\n\n  // auto_start_session is true by default\n  if (options.auto_start_session || typeof options.auto_start_session == 'undefined') {\n    return this.client.launchBrowser().then(browser => {\n      this.browser = browser;\n    });\n  }\n});\n\nAfter(async function(testCase) {\n\n  //send test-case result to cloud provider\n  const {result} = testCase;\n  if (this.client && result) {\n    const error = result.status === 'FAILED' ? new Error(result.message) : null;\n    await this.client.transport.testSuiteFinished(error);\n  }\n\n  if (this.browser?.sessionId) {\n    await this.browser.quit();\n  }\n});\n"
  },
  {
    "path": "lib/runner/test-runners/cucumber/nightwatch-format.js",
    "content": "const Utils = require('../../../utils');\nconst {Logger, SafeJSON, isFunction} = Utils;\nconst {Formatter} = require('@cucumber/cucumber');\n\nconst {NightwatchEventHub, CUCUMBER_RUNNER_EVENTS: {\n  TestStarted,\n  TestFinished,\n  TestCaseStarted,\n  TestCaseFinished,\n  TestStepStarted,\n  TestStepFinished\n}} = require('../../eventHub.js');\n\nmodule.exports = class NightwatchFormatter extends Formatter {\n  constructor(options) {\n    super(options);\n\n    this.report = {};\n\n    NightwatchFormatter.eventBroadcaster = options.eventBroadcaster;\n\n    options.eventBroadcaster.on('envelope', (envelope) => {\n      this.reportHandler(envelope);\n    });\n  }\n\n  static setCapabilities(data) {\n    data = {...data, testCaseStartedId: process.env.CUCUMBER_TEST_CASE_STARTED_ID};\n\n    if (isFunction(process.send)) {\n      process.send({\n        'jsonEnvelope': SafeJSON.stringify({\n          session: {\n            ...data,\n            workerId: process.env.CUCUMBER_WORKER_ID\n          }\n        }),\n        'POST_SESSION_EVENT': SafeJSON.stringify({\n          session: {\n            ...data,\n            workerId: process.env.CUCUMBER_WORKER_ID\n          }\n        })\n      });\n    } else {\n      NightwatchFormatter.eventBroadcaster?.emit('envelope', {session: data});\n    }\n  }\n\n  onSessionCapabilities(envelope) {\n    this.report.session = this.report.session || {};\n\n    this.report.session[envelope.testCaseStartedId] = envelope;\n  }\n\n  onMeta(meta) {\n    this.report.metadata = meta;\n  }\n\n  onGherkinDocument(gherkinDocument) {\n    this.report.gherkinDocument = [...(this.report.gherkinDocument || []), gherkinDocument];\n  }\n\n  onParseError(parseError) {\n    this.report.error = [...(this.report.error || []), parseError];\n  }\n\n  onPickle(pickle) {\n    this.report.pickle = [...(this.report.pickle || []), pickle];\n  }\n\n  onHook(hook) {\n    this.report.hooks = [...(this.report.hooks || []), hook];\n  }\n\n  onSource(source) {\n    this.report.source = source;\n  }\n\n  onStepDefinition(stepDefinition) {\n    this.report.stepDefinition = [...(this.report.stepDefinition || []), stepDefinition];\n  }\n\n  onTestCase(testCase) {\n    this.report.testCases = [...(this.report.testCases || []), testCase];\n  }\n\n  onTestCaseFinished(result) {\n    result.httpOutput = Logger.collectTestSectionOutput();\n\n    this.report.testCaseFinished = this.report.testCaseFinished || {};\n    this.report.testCaseFinished[result.testCaseStartedId] = result;\n\n    NightwatchEventHub.emit(TestCaseFinished, {\n      envelope: result,\n      report: this.report\n    });\n  }\n\n  onTestCaseStarted(result) {\n    this.report.testCaseStarted = this.report.testCaseStarted || {};\n    this.report.testCaseStarted[result.id] = result;\n\n    NightwatchEventHub.emit(TestCaseStarted, {\n      envelope: result,\n      report: this.report\n    });\n  }\n\n  onTestRunFinished(result) {\n    result.httpOutput = Logger.collectOutput();\n    this.report.testRunFinished = result;\n\n    NightwatchEventHub.emit(TestFinished, {\n      envelope: result,\n      report: this.report\n    });\n  }\n\n  onTestRunStarted(result) {\n    this.report.testRunStarted = result;\n\n    NightwatchEventHub.emit(TestStarted, {\n      envelope: result,\n      report: this.report\n    });\n  }\n\n  onTestStepFinished(result) {\n    result.httpOutput = Logger.collectCommandOutput();\n    this.report.testStepFinished = this.report.testStepFinished || {};\n    this.report.testStepFinished[result.testCaseStartedId] = result;\n\n    NightwatchEventHub.emit(TestStepFinished, {\n      envelope: result,\n      report: this.report\n    });\n  }\n\n  onTestStepStarted(result) {\n    this.report.testStepStarted = this.report.testStepStarted || {};\n    this.report.testStepStarted[result.testCaseStartedId] = result;\n\n    NightwatchEventHub.emit(TestStepStarted, {\n      envelope: result,\n      report: this.report\n    });\n  }\n\n  reportHandler(envelope) {\n    try {\n      if (!NightwatchEventHub.isAvailable) {\n        return;\n      }\n\n      const handlers = {\n        meta: this.onMeta,\n        gherkinDocument: this.onGherkinDocument,\n        parseError: this.onParseError,\n        pickle: this.onPickle,\n        source: this.onSource,\n        stepDefinition: this.onStepDefinition,\n        testCase: this.onTestCase,\n        hook: this.onHook,\n        testCaseFinished: this.onTestCaseFinished,\n        testCaseStarted: this.onTestCaseStarted,\n        testRunFinished: this.onTestRunFinished,\n        testRunStarted: this.onTestRunStarted,\n        testStepFinished: this.onTestStepFinished,\n        testStepStarted: this.onTestStepStarted,\n        session: this.onSessionCapabilities\n      };\n\n      const cucumberEvent = Object.keys(envelope)[0];\n      if (cucumberEvent && handlers[cucumberEvent]) {\n        handlers[cucumberEvent].call(this, envelope[cucumberEvent]);\n      }\n    } catch (err) {\n      Logger.error(err);\n    }\n  }\n};\n"
  },
  {
    "path": "lib/runner/test-runners/cucumber.js",
    "content": "const path = require('path');\nconst Runner = require('./default');\nconst TestSuite =  require('../../testsuite');\nconst {Logger, isString, isDefined} = require('../../utils');\nconst {NightwatchEventHub} = require('../eventHub.js');\nconst {getTestSourceForRerunFailed} = require('../rerunUtil.js');\nconst DefaultSettings = require('../../settings/defaults.js');\n\nclass CucumberSuite extends TestSuite {\n  static isSessionCreateError(err) {\n    return [\n      'You appear to be executing an install of cucumber',\n      'Must be locally installed.'\n    ].some(item => err.message.includes(item));\n  }\n\n  static createCli(settings) {\n    let CucumberCli;\n\n    try {\n      CucumberCli = require('@cucumber/cucumber/lib/cli/index').default;\n    } catch (err) {\n      if (err.code === 'MODULE_NOT_FOUND') {\n        const error = new Error('Cucumber needs to be installed as a project dependency.');\n        error.showTrace = false;\n        error.detailedErr = 'You can install cucumber from NPM using:\\n\\n        ' + Logger.colors.light_green('npm i @cucumber/cucumber');\n\n        throw error;\n      }\n\n      err.showTrace = false;\n      err.sessionCreate = true;\n\n      throw err;\n    }\n\n    return CucumberCli;\n  }\n\n  static get cucumberSetupFile() {\n    return path.join(__dirname, './cucumber/_setup_cucumber_runner.js');\n  }\n\n  constructor({modulePath, modules, settings, argv}) {\n    super({modulePath, modules, settings, argv, addtOpts: {\n      globalHooks: {}\n    }});\n\n    // force all nightwatch commands to return promise\n    this.settings.always_async_commands = true;\n\n    const minWorkersCount = 2;\n    const {options = {}} = this.settings.test_runner;\n    if (this.argv.parallel) {\n      const argvParallelCount = Number(this.argv.parallel);\n      this.usingCucumberWorkers = Math.max(argvParallelCount, options.parallel || minWorkersCount);\n    }\n\n    this.reporter = {\n      testSuiteFinished() {},\n      allTestsPassed: true\n    };\n\n    try {\n      this.createCucumberCli();\n    } catch (err) {\n      const {message} = err;\n\n      if (!err.detailedErr) {\n        err.detailedErr = message;\n        err.message = 'An error occurred while trying to initialize the Cucumber runner:';\n      }\n\n      err.sessionCreate = true;\n\n      Logger.error(err);\n\n      throw err;\n    }\n  }\n\n  createCucumberCli() {\n    const CucumberCli = CucumberSuite.createCli(this.settings);\n    const argv = this.getCliArgvForCucumber();\n\n    this.cucumberCli = new CucumberCli({\n      argv,\n      env: process.env,\n      cwd: process.cwd(),\n      stdout: process.stdout\n    });\n  }\n\n  shouldUseNightwatchFormatter(options) {\n    return (NightwatchEventHub.isAvailable ||\n      options.format === 'nightwatch-format' ||\n      this.argv.format === 'nightwatch-format'\n    );\n  }\n\n  getCliArgvForCucumber() {\n    const specs = this.createInitialRequires();\n    const {options} = this.settings.test_runner;\n\n    if ((process.env.NIGHTWATCH_RERUN_FAILED === 'true' || this.argv['rerun-failed'])) {\n      options.feature_path = getTestSourceForRerunFailed(this.settings);\n    }\n\n    if (options.feature_path && !Array.isArray(options.feature_path)) {\n      options.feature_path = [options.feature_path];\n    }\n\n    if (this.shouldUseNightwatchFormatter(options)) {\n      options.format = [...(options.format || []), path.join(__dirname, './cucumber/nightwatch-format.js')];\n    }\n\n    const {feature_path = ''} = options;\n    const parallelArgs = this.usingCucumberWorkers ? ['--parallel', this.usingCucumberWorkers] : [];\n    const additionalOptions = this.buildArgvValue(['tags', 'retry-tag-filter', 'profile', 'format', 'format-options', 'dry-run', 'fail-fast', ['retry', 'retries'], 'no-strict', 'name']);\n    const extraParams = ['--world-parameters', JSON.stringify({...this.argv, settings: this.settings})];\n\n    return [\n      process.execPath,\n      require.resolve('@cucumber/cucumber')\n    ].concat(feature_path, parallelArgs, specs, additionalOptions, extraParams);\n  }\n\n  createInitialRequires() {\n    const {options} = this.settings.test_runner;\n    const isESMEnable = options.enable_esm ||  this.argv['enable-esm'];\n    const importTypeArgument = isESMEnable ? '--import' : '--require';\n    const initialRequires = [\n      importTypeArgument, CucumberSuite.cucumberSetupFile\n    ];\n\n    if (isESMEnable){\n      initialRequires.push(...this.buildArgvValue(['import']));\n    } else {\n      initialRequires.push(...this.buildArgvValue(['require', 'require-module']));\n    }\n\n    return this.allModulePaths.reduce((prev, spec) => {\n      prev.push(importTypeArgument, spec);\n\n      return prev;\n    }, initialRequires);\n  }\n\n  mergeCliConfigValues(key) {\n    const {options = {}} = this.settings.test_runner;\n\n    return Array.from(new Set([\n      ...(Array.isArray(this.argv[key]) ? this.argv[key] : (isString(this.argv[key]) ? [this.argv[key]] : [])),\n      ...(Array.isArray(options[key]) ? options[key] : (isString(options[key]) ? [options[key]] : []))\n    ]));\n  }\n\n  buildArgvValue(argNames) {\n    if (isString(argNames)) {\n      argNames = [argNames];\n    }\n\n    return argNames.reduce((prev, argName) => {\n      let key = argName;\n\n      if (Array.isArray(argName) && argName.length === 2) {\n        key = argName[0];\n        argName = argName[1];\n      }\n\n      const {options = {}} = this.settings.test_runner;\n\n      const allArgv = {\n        ...options,\n        ...this.argv,\n        require: this.mergeCliConfigValues('require'),\n        requireModule: this.mergeCliConfigValues('requireModule'),\n        format: this.mergeCliConfigValues('format'),\n        paths: this.mergeCliConfigValues('paths'),\n        import: this.mergeCliConfigValues('import')\n      };\n\n      if ((isDefined(allArgv[argName]) && allArgv[argName] !== '') ||\n          (isDefined(allArgv[key]) && allArgv[key] !== '')\n      ) {\n        let argValues = allArgv[argName] || allArgv[key];\n        if (!Array.isArray(argValues)) {\n          argValues = [argValues];\n        }\n\n        argValues.forEach(value => {\n          const args = [`--${key}`];\n          if (value !== true) {\n            args.push(value);\n          }\n\n          prev.push(...args);\n        });\n      }\n\n      return prev;\n    }, []);\n  }\n\n  onTestSuiteFinished(result) {\n    const failures = result.success === false;\n\n    return super.onTestSuiteFinished(failures);\n  }\n\n  testSuiteFinished() {}\n\n  async runTestSuite() {\n    let result;\n    try {\n      result = await this.cucumberCli.run();\n    } catch (err) {\n      if (CucumberSuite.isSessionCreateError(err)) {\n        const {message} = err;\n        err.message = 'An error occurred while trying to start Cucumber CLI:';\n        err.detailedErr = message;\n        err.sessionCreate = true;\n        err.showTrace = false;\n\n        Logger.error(err);\n\n        throw err;\n      }\n\n      if (err.sessionCreate && !this.usingCucumberWorkers) {\n        throw err;\n      }\n\n      if (!this.isAssertionError(err)) {\n        Logger.error(err);\n\n        throw err;\n      }\n\n      result = err;\n    }\n\n    return result;\n  }\n}\n\nclass CucumberRunnner extends Runner {\n  get supportsConcurrency() {\n    return true;\n  }\n\n  get supportsParallelTestSuiteRun() {\n    return false;\n  }\n\n  get type() {\n    return 'cucumber';\n  }\n\n  constructor(settings, argv, addtOpts) {\n    super(settings, argv, addtOpts);\n\n    // Disable HTML Reporter as it is not yet supported in Cucumber.\n    const reporterFile = this.globalReporter.reporterFile;\n    if (reporterFile && reporterFile.includes('html')) {\n      if (reporterFile.toString() !== DefaultSettings.default_reporter.toString()) {\n        // user has specifically asked for HTML report.\n        // eslint-disable-next-line no-console\n        console.warn(Logger.colors.yellow('HTML reporter is not supported with Cucumber runner.'));\n      }\n\n      const index = reporterFile.indexOf('html');\n      if (index > -1) {\n        reporterFile.splice(index, 1);\n      }\n    }\n  }\n\n  hasTestFailures(result) {\n    return result && result.success === false;\n  }\n\n  createTestSuite({modulePath, modules}) {\n    const {settings, argv, addtOpts} = this;\n\n    return new CucumberSuite({modulePath, modules, settings, argv, addtOpts});\n  }\n\n  async runTests(modules) {\n    const modulePath = modules.slice(0).shift();\n    this.currentSuite = this.createTestSuite({modulePath, modules});\n\n    return await this.currentSuite.runTestSuite();\n  }\n}\n\nmodule.exports = CucumberRunnner;\n"
  },
  {
    "path": "lib/runner/test-runners/default.js",
    "content": "const {GlobalReporter} = require('../../reporter');\nconst TestSuite = require('../../testsuite');\nconst Concurrency = require('../concurrency');\nconst {Logger} = require('../../utils');\n\nclass DefaultRunner {\n  get supportsConcurrency() {\n    return true;\n  }\n\n  get type() {\n    return 'nightwatch';\n  }\n\n  constructor(settings, argv, addtOpts) {\n    this.startTime = new Date().getTime();\n    this.settings = settings;\n    this.argv = argv;\n    this.addtOpts = addtOpts;\n    this.publishReport = true; // in-case of an uncaught exception, the report will not be published\n    this.globalReporter = new GlobalReporter(argv.reporter, settings, {\n      openReport: argv.open,\n      reportFileName: argv['report-filename']\n    });\n  }\n\n  get client() {\n    return this.currentSuite && this.currentSuite.client;\n  }\n\n  get results() {\n    return this.globalReporter.globalResults;\n  }\n\n  hasTestFailures() {\n    return this.globalReporter.hasTestFailures();\n  }\n\n  registerUncaughtErr(err) {\n    this.globalReporter.registerUncaughtErr(err);\n  }\n\n  /**\n   * @param {Error} [err]\n   * @return {Promise}\n   */\n  closeOpenSessions(err) {\n    const inspectorServer = this.addtOpts?.globalsInstance?.inspectorServer;\n    if (inspectorServer) {\n      inspectorServer.closeSocket();\n    }\n\n    if (this.client?.sessionId && this.client?.startSessionEnabled) {\n      Logger.info(`Attempting to close session ${this.client.sessionId}...`);\n\n      const failures = !this.currentSuite.reporter.allTestsPassed;\n\n      return this.currentSuite.terminate(failures ? 'FAILED' : '', null, true);\n    }\n\n    return Promise.resolve();\n  }\n\n  async createTestSuite({modulePath, modules}) {\n    const {settings, argv, addtOpts} = this;\n\n    const testSuite = new TestSuite({modulePath, modules, settings, argv, addtOpts});\n    await testSuite.init();\n\n    return testSuite;\n  }\n\n  async runTestSuite(modulePath, modules) {\n    try {\n      this.currentSuite = await this.createTestSuite({modulePath, modules});\n    } catch (err) {\n      const Runner = require('../runner.js');\n      throw Runner.createError(err);\n    }\n\n    let possibleErr;\n    try {\n      await this.currentSuite.run();\n    } catch (err) {\n      possibleErr = err;\n    }\n\n    if (!this.argv['launch-url']) {\n      this.globalReporter.addTestSuiteResults(this.currentSuite.reporter.exportResults());\n    }\n\n    if (possibleErr instanceof Error) {\n      throw possibleErr;\n    }\n  }\n\n  async promiseFn(resolve, reject) {\n    const sourcePath = this.modulePathsCopy.shift();\n\n    try {\n      await this.runTestSuite(sourcePath, this.fullPaths);\n\n      if (this.modulePathsCopy.length === 0) {\n        resolve();\n      } else {\n        await this.promiseFn(resolve, reject);\n      }\n    } catch (err) {\n      reject(err);\n    }\n  }\n\n  printGlobalResults() {\n    this.globalReporter.create(this.startTime).print();\n\n    return this;\n  }\n\n  /**\n   * @param {Array} modules\n   * @return {Promise}\n   */\n  runTests(modules) {\n    this.modulePathsCopy = modules.slice(0);\n    this.fullPaths = modules;\n\n    return new Promise(this.promiseFn.bind(this));\n  }\n\n  /**\n   * @return {Promise<boolean>}\n   */\n  async reportResults() {\n    if (!this.isTestWorker()) {\n      this.printGlobalResults();\n      await this.globalReporter.save();\n    }\n  }\n\n  /**\n   *\n   * @param {Array} testEnvArray\n   * @param {Array} modules\n   * @return {Promise<number>}\n   */\n  async runConcurrent(testEnvArray, modules, isTestWorkerEnabled, isSafariEnvPresent) {\n    this.concurrency = new Concurrency(this.settings, this.argv, isTestWorkerEnabled, isSafariEnvPresent);\n    this.globalReporter.setupChildProcessListener(this.concurrency);\n\n    const exitCode = await this.concurrency.runMultiple(testEnvArray, modules);\n    await this.reportResults();\n\n    return exitCode;\n  }\n\n  isTestWorker() {\n    return Concurrency.isTestWorker(this.argv);\n  }\n\n  /**\n   * Main entry-point of the runner\n   *\n   * @return {Promise}\n   */\n  async run(modules) {\n    let possibleErr;\n    let result;\n\n    try {\n      result = await this.runTests(modules);\n    } catch (err) {\n      if (this.modulePathsCopy && this.modulePathsCopy.length > 0) {\n        this.globalReporter.skippedSuites = this.modulePathsCopy.length;\n      }\n      possibleErr = err;\n    }\n\n    await this.closeOpenSessions();\n\n    if (this.publishReport) {\n      await this.reportResults();\n    }\n\n    if (possibleErr) {\n      throw possibleErr;\n    }\n\n    return this.hasTestFailures(result);\n  }\n}\n\nmodule.exports = DefaultRunner;\n"
  },
  {
    "path": "lib/runner/test-runners/mocha/custom-runnable.js",
    "content": "module.exports = async function(fn, isHook = false) {\n  const self = this;\n  const start = new Date();\n  const ctx = this.ctx;\n  let finished;\n\n  if (this.isPending()) {\n    return fn();\n  }\n\n  let emitted;\n  if (!isHook) {\n    this._enableTimeouts = false;\n  }\n\n  // Sometimes the ctx exists, but it is not runnable\n  if (ctx && ctx.runnable) {\n    ctx.runnable(this);\n  }\n\n  // called multiple times\n  function multiple(err) {\n    if (emitted) {\n      return;\n    }\n    emitted = true;\n    const msg = 'done() called multiple times';\n    if (err && err.message) {\n      err.message += ` (and Mocha's ${msg})`;\n      self.emit('error', err);\n    } else {\n      self.emit('error', new Error(msg));\n    }\n  }\n\n  // finished\n  function done(err) {\n    const ms = self.timeout();\n    if (self.timedOut) {\n      return;\n    }\n\n    if (finished) {\n      return multiple(err);\n    }\n\n    self.clearTimeout();\n    self.duration = new Date() - start;\n    finished = true;\n    if (!err && self.duration > ms && self._enableTimeouts) {\n      err = new Error('Timeout of ' + ms +\n        'ms exceeded. For async tests and hooks, ensure \"done()\" is called; if returning a Promise, ensure it resolves.');\n    }\n    fn(err);\n  }\n\n  this.callback = done;\n\n  this.resetTimeout();\n  try {\n    const args = [this.parent.client.api];\n    let userCalled = false;\n\n    const onFinished = function(err) {\n      if (err instanceof Error) {\n        return done(err);\n      }\n\n      if (err) {\n        if (Object.prototype.toString.call(err) === '[object Object]') {\n          return done(new Error('done() invoked with non-Error: ' +\n            JSON.stringify(err)));\n        }\n\n        return done(new Error('done() invoked with non-Error: ' + err));\n      }\n\n      done();\n    };\n\n    const {nightwatchSuite} = this.parent;\n\n    let err = await nightwatchSuite.handleRunnable(this.title, () => {\n      this.parent.nightwatchSuite.reporter.testResults.resetLastError();\n\n      if (isHook && this.async === 2) {\n        return new Promise((resolve, reject) => {\n          args.push(function(err) {\n            userCalled = true;\n\n            setTimeout(function() {\n              if (err instanceof Error) {\n                reject(err);\n              } else {\n                resolve();\n              }\n              onFinished(err);\n            }, 10);\n          });\n\n          this.fn.apply(ctx, args);\n        });\n      }\n\n      const result = this.fn.apply(ctx, args);\n\n      if (result instanceof Promise) {\n        return result;\n      }\n    });\n\n    if (err && !(err instanceof Error)) {\n      err = undefined;\n    }\n\n    if (this.async <= 1) {\n      const {lastError} = this.parent.nightwatchSuite.reporter.testResults;\n      if (!err && lastError) {\n        err = lastError;\n      }\n      done(err);\n      emitted = true;\n    }\n  } catch (err) {\n    done(err);\n    emitted = true;\n  }\n};\n"
  },
  {
    "path": "lib/runner/test-runners/mocha/custom-runner.js",
    "content": "const Mocha = require('mocha');\nconst {adaptRunnables} = require('./extensions.js');\n\nmodule.exports = class CustomRunner extends Mocha.Runner {\n  async runSuite(suite, fn) {\n    const isMainSuite = suite.parent && suite.parent.root;\n\n    const createSession = () => {\n      return new Promise(function(resolve, reject) {\n        if (isMainSuite) {\n          try {\n            if (suite.file) {\n              suite.nightwatchSuite.setModulePath(suite.file);\n            }\n\n            suite.nightwatchSuite\n              .updateClient()\n              .setupHooks()\n              .startTestSuite()\n              .then(data => resolve(data))\n              .catch(err => reject(err));\n          } catch (err) {\n            reject(err);\n          }\n        } else {\n          if (!suite.root && suite.parent.nightwatchSuite) {\n            suite.nightwatchSuite.createClient(suite.parent.nightwatchSuite.client);\n            suite.nightwatchSuite.reporter = suite.parent.nightwatchSuite.reporter;\n          }\n          resolve(false);\n        }\n      });\n    };\n\n    const onSuiteFinished = (err) => {\n      if (!suite.nightwatchSuite) {\n        return fn(err);\n      }\n\n      suite.nightwatchSuite.onTestSuiteFinished().then(failures => {\n        fn(err);\n      }).catch(suiteError => {\n        console.error(suiteError);\n        suiteError = suiteError || err;\n        fn(suiteError);\n      });\n    };\n\n    try {\n      if (suite.disabled) {\n        // eslint-disable-next-line no-console\n        console.log(`Testsuite \"${suite.title}\" is disabled, skipping...`);\n\n        return fn();\n      }\n\n      if (suite['@nightwatch_promise']) {\n        await suite['@nightwatch_promise']();\n      }\n\n      // create the nightwatch session\n      const sessionInfo = await createSession();\n    } catch (err) {\n      // an error occurred while trying to create the session\n      this.failures = err;\n\n      return onSuiteFinished(err);\n    }\n\n    // run the mocha suite\n    return super.runSuite(suite, onSuiteFinished);\n  }\n\n  run(fn) {\n    adaptRunnables(this.suite);\n\n    super.run(fn);\n  }\n};\n"
  },
  {
    "path": "lib/runner/test-runners/mocha/extensions.js",
    "content": "const Utils = require('../../../utils');\nconst customRunnable = require('./custom-runnable.js');\nconst nightwatchSuiteUtils = require('./nightwatchSuite.js');\nconst {Logger} = Utils;\n\nmodule.exports = class Extensions {\n  static adaptRunnables(parent) {\n    Extensions.adaptHooks(parent, ['_afterAll', '_afterEach', '_beforeAll', '_beforeEach']);\n\n    parent.tests = parent.tests.map(function(test) {\n      test.run = function(...args) {\n        // eslint-disable-next-line no-console\n        console.log(`\\n  Running ${Logger.colors.green(this.title)}${Logger.colors.stack_trace('...')}`);\n\n        this.parent.client.isES6AsyncTestcase = Utils.isES6AsyncFn(this.fn);\n        delete this.parent.client.isES6AsyncTestHook;\n\n        return customRunnable.apply(this, args);\n      }.bind(test);\n\n      return test;\n    });\n\n    if (parent.suites && parent.suites.length > 0) {\n      parent.suites.forEach(function(item) {\n        return (function(_item) {\n          Extensions.adaptRunnables(_item);\n        })(item);\n      });\n    }\n\n  }\n\n  static adaptHooks(suite, hooks) {\n    hooks.forEach(function(hook) {\n      suite[hook].forEach(hookInstance => {\n        const originalRunFn = hookInstance.run;\n        hookInstance.run = function(fn) {\n          const isAsync = Utils.isES6AsyncFn(this.fn);\n          //console.log(`  Running ${Logger.colors.stack_trace(this.title + ':')}`);\n          this.parent.client.isES6AsyncTestcase = isAsync;\n\n          if (this.fn.length === 0 && isAsync) {\n            return originalRunFn.call(this, fn);\n          }\n\n          return customRunnable.call(this, fn, true);\n        }.bind(hookInstance);\n      });\n    });\n  }\n\n  static augmentTestSuite({suite, runner, argv, settings, addtOpts}) {\n    const attributes = [\n      'tags',\n      'desiredCapabilities',\n      'endSessionOnFail',\n      'skipTestcasesOnFail',\n      'unitTest',\n      'disabled'\n    ];\n\n    Object.defineProperties(suite, attributes.reduce((prev, attribute) => {\n      prev[attribute] = {\n        configurable: true,\n        set: function(value) {\n          this.nightwatchSuite.mochaContext.then(context => {\n            context.setAttribute(`@${attribute}`, value);\n          });\n        },\n\n        get: function() {\n          if (!this.nightwatchSuite || !this.nightwatchSuite.context) {\n            return null;\n          }\n\n          return this.nightwatchSuite.context.getAttribute(`@${attribute}`);\n        }\n      };\n\n      return prev;\n    }, {}));\n\n    const suiteIndex = Math.max(0, runner.suite.suites.length - 1);\n\n    const nightwatchSuite = nightwatchSuiteUtils.create({\n      runner,\n      suite,\n      settings,\n      argv,\n      addtOpts,\n      modulePath: runner.files[suiteIndex]\n    });\n\n    suite['@nightwatch_promise'] = function() {\n      return nightwatchSuite.init({suite, nightwatchSuite});\n    };\n\n    if (Utils.isUndefined(suite.timeout())) {\n      suite.timeout(30000);\n    }\n  }\n};\n"
  },
  {
    "path": "lib/runner/test-runners/mocha/nightwatchSuite.js",
    "content": "const TestSuite = require('../../../testsuite');\n\nmodule.exports.create = function ({suite, settings, argv, modulePath, addtOpts, runner}) {\n  const modules = [];\n  const timeoutFn = suite.timeout;\n  const nightwatchSuite = new TestSuite({\n    modules,\n    settings,\n    argv,\n    usingMocha: true,\n    addtOpts,\n    modulePath\n  });\n\n  Object.defineProperties(suite, {\n    nightwatchSuite: {\n      configurable: true,\n      get: function() {\n        return nightwatchSuite;\n      }\n    },\n\n    client: {\n      configurable: true,\n      get: function() {\n        return this.nightwatchSuite.client;\n      }\n    },\n\n    isWorker: {\n      configurable: true,\n      get: function() {\n        return runner.isWorker;\n      }\n    },\n\n    files: {\n      configurable: true,\n      get: function() {\n        return runner.files;\n      }\n    },\n\n    mochaOptions: {\n      configurable: true,\n      get: function() {\n        return runner.options;\n      }\n    }\n  });\n\n  Object.defineProperties(suite, {\n    globals: {\n      get: function() {\n        return this.nightwatchSuite.settings.globals;\n      }\n    },\n\n    settings: {\n      get: function() {\n        return this.nightwatchSuite.settings;\n      }\n    },\n\n    argv: {\n      get: function() {\n        return this.nightwatchSuite.argv;\n      }\n    },\n\n    suiteRetries: {\n      value: function(value) {\n        if (typeof value != 'undefined') {\n          this.nightwatchSuite.mochaContext.then(context => {\n            context.setSuiteRetries(value);\n          });\n        }\n      }\n    },\n\n    waitForTimeout: {\n      value: function(value) {\n        if (typeof value == 'undefined') {\n          return this.globals.waitForConditionTimeout;\n        }\n        this.globals.waitForConditionTimeout = value;\n        this.globals.retryAssertionTimeout = value;\n      }\n    },\n\n    timeout: {\n      value: function(value) {\n        if (typeof value == 'undefined') {\n          return timeoutFn.call(this);\n        }\n\n        this.globals.unitTestsTimeout = value;\n\n        timeoutFn.call(this, value);\n      }\n    },\n\n    waitForRetryInterval: {\n      value: function(value) {\n        if (typeof value == 'undefined') {\n          return this.globals.waitForConditionPollInterval;\n        }\n\n        this.globals.waitForConditionPollInterval = value;\n      }\n    }\n  });\n\n  return nightwatchSuite;\n};\n\nmodule.exports.init = function({suite, nightwatchSuite}) {\n  return nightwatchSuite.initCommon({\n    suiteTitle: suite.title\n  }).catch(err => {\n    console.error(err);\n    process.exit(1);\n  });\n};\n"
  },
  {
    "path": "lib/runner/test-runners/mocha.js",
    "content": "const path = require('path');\nconst Concurrency = require('../concurrency');\nconst Utils = require('../../utils');\nconst {Logger} = Utils;\nconst {augmentTestSuite} = require('./mocha/extensions.js');\n\nclass MochaRunner {\n  static MochaNightwatch({argv, settings, addtOpts}) {\n    const Mocha = require('mocha');\n    const CustomRunner = require('./mocha/custom-runner.js');\n\n    return class MochaNightwatch extends Mocha {\n      constructor(mochaOpts, nightwatchSettings) {\n        super(mochaOpts);\n        this.nightwatchSettings = nightwatchSettings;\n        this._runnerClass = CustomRunner;\n\n        const runner = this;\n\n        this.suite.on('suite', function (suite) {\n          suite.on('suite', function (childSuite) {\n            augmentTestSuite({suite: childSuite, runner, argv, settings, addtOpts});\n          });\n\n          augmentTestSuite({suite, runner, argv, settings, addtOpts});\n        });\n      }\n    };\n  }\n\n  get supportsConcurrency() {\n    return true;\n  }\n\n  get combinedReporterList() {\n    return ['mochawesome', 'html'];\n  }\n\n  get type() {\n    return 'mocha';\n  }\n\n  constructor(settings, argv, addtOpts = {}) {\n    this.startTime = new Date().getTime();\n    this.settings = settings;\n    this.argvOpts = argv;\n    this.publishReport = false;\n    this.argv = argv;\n    this.processListener = addtOpts.processListener;\n\n    this.mochaOpts = settings.test_runner.options || {};\n    if (Utils.isUndefined(this.mochaOpts.timeout)) {\n      this.mochaOpts.timeout = settings.globals.asyncHookTimeout;\n    }\n\n    if (this.settings.disable_colors) {\n      this.mochaOpts.color = false;\n    }\n\n    if (this.mochaOpts.reporter === 'junit') {\n      this.mochaOpts.reporter = 'mocha-junit-reporter';\n    }\n\n    if (argv.reporter.includes('mochawesome')) {\n      this.mochaOpts.reporter = 'mochawesome';\n    } else if (argv.reporter.includes('mocha-junit-reporter')) {\n      try {\n        require('mocha-junit-reporter');\n      } catch (err) {\n        const error = new Error('Nightwatch needs the mocha-junit-reporter package for when using Mocha as a test runner.');\n        error.detailedErr = 'To install it, please run:\\n    npm install mocha-junit-reporter --save-dev';\n        error.showTrace = false;\n        error.displayed = false;\n\n        throw error;\n      }\n      this.mochaOpts.reporter = 'mocha-junit-reporter';\n    }\n\n    if (this.mochaOpts.reporter === 'mochawesome') {\n      try {\n        require('mochawesome');\n      } catch (err) {\n        const error = new Error('Nightwatch needs the mochawesome package for when using Mocha as a test runner.');\n        error.detailedErr = 'To install it, please run:\\n    npm install mochawesome --save-dev';\n        error.showTrace = false;\n        error.displayed = false;\n\n        throw error;\n      }\n    }\n\n    if (argv.grep) {\n      this.mochaOpts.grep = argv.grep;\n    }\n\n    if (argv['fail-fast']) {\n      this.mochaOpts.bail = true;\n    }\n\n    if (argv.retries) {\n      this.mochaOpts.retries = argv.retries;\n    }\n\n    if (argv.fgrep) {\n      this.mochaOpts.fgrep = argv.fgrep;\n    }\n\n    if (argv.invert) {\n      this.mochaOpts.invert = argv.invert;\n    }\n\n    this.mochaOpts.reporterOptions = this.mochaOpts.reporterOptions || {};\n\n    if (argv.reporter.includes('mocha-junit-reporter')) {\n      this.mochaOpts.reporterOptions.mochaFile = path.join(settings.output_folder, 'test-results.xml');\n    }\n\n    if (this.isTestWorker()) {\n      const filePath = this.argv.test;\n      const reportFilename = filePath.substring(filePath.lastIndexOf('/') + 1).split('.')[0];\n      this.mochaOpts.isWorker = true;\n\n      if (argv.reporter.includes('mocha-junit-reporter')) {\n        this.mochaOpts.reporterOptions.mochaFile = path.join(settings.output_folder, `${reportFilename}.xml`);\n      } else if (argv.reporter.includes('mochawesome')) {\n        this.mochaOpts.reporterOptions = Object.assign(this.mochaOpts.reporterOptions, {\n          html: false,\n          json: true,\n          quiet: true,\n          reportFilename\n        });\n      }\n    }\n\n    if (this.mochaOpts.reporter === 'mochawesome' && !this.mochaOpts.reporterOptions.reportDir) {\n      this.mochaOpts.reporterOptions.reportDir =  settings.reportDir || 'html-report';\n    }\n\n    const MochaNightwatch = MochaRunner.MochaNightwatch({settings, argv, addtOpts});\n    this.mocha = new MochaNightwatch(this.mochaOpts, settings);\n  }\n\n  async runConcurrent(testEnvArray, modules) {\n    this.checkReporterDependencies();\n\n    this.concurrency = new Concurrency(this.settings, this.argv);\n    const exitCode = await this.concurrency.runMultiple(testEnvArray, modules);\n\n    await this.generateCombinedReport();\n\n    return exitCode;\n  }\n\n  checkReporterDependencies() {\n    if (!this.argv.reporter.includes('mochawesome')) {\n      return;\n    }\n\n    try {\n      require('mochawesome-report-generator');\n      require('mochawesome-merge');\n    } catch (err) {\n      const error = new Error('Nightwatch needs some more packages when running in parallel and using the mochawesome reporter:');\n      error.detailedErr = 'To install dependencies, please run:\\n    npm install mochawesome-report-generator mochawesome-merge --save-dev';\n\n      throw error;\n    }\n  }\n\n  async generateCombinedReport() {\n    if (!this.argv.reporter.includes('mochawesome')) {\n      return;\n    }\n\n    const {reportDir} = this.mochaOpts.reporterOptions;\n    const marge = require('mochawesome-report-generator');\n    const {merge} = require('mochawesome-merge');\n    const files = reportDir ? `${path.join(reportDir, '*.json')}` : './mochawesome-report/*.json';\n\n    const report = await merge({\n      files: [files]\n    });\n\n    return marge.create(report, {});\n  }\n\n  isTestWorker() {\n    return this.argv['test-worker'];\n  }\n\n  closeOpenSessions() {\n    const mochaSuite = this.mocha.suite;\n    const client = mochaSuite && mochaSuite.client;\n\n    if (client && client.sessionId) {\n      const request = client.transport.createHttpRequest({\n        path: `/session/${client.sessionId}`\n      });\n\n      return new Promise(function(resolve, reject) {\n        request.delete()\n          .on('error', function(err) {\n            resolve();\n          })\n          .on('success', function() {\n            resolve();\n          });\n      });\n    }\n\n    return Promise.resolve();\n  }\n\n  registerUncaughtErr(err) {\n  }\n  /**\n   * Main entry-point of the runner\n   *\n   * @return {Promise}\n   */\n  run(modules) {\n    modules.forEach(module => this.mocha.addFile(module));\n\n    return new Promise((resolve, reject) => {\n      this.mocha.run(failures => {\n        if ((failures instanceof Error) && failures.sessionCreate) {\n          Logger.error(failures);\n          process.exit(1);\n        }\n\n\n        this.closeOpenSessions()\n          .then(_ => {\n            if (this.mocha.suite && this.mocha.suite.client) {\n              return this.mocha.suite.client.transport.sessionFinished();\n            }\n          })\n          .catch(err => {\n            console.error(err.stack);\n          })\n          .then(_ => {\n            if (failures) {\n              let err;\n              if (failures instanceof Error) {\n                err = failures;\n              } else {\n                err = new Error('Mocha reported test failures.');\n                err.failures = failures;\n              }\n\n              return reject(err);\n            }\n\n            resolve();\n          });\n      });\n    });\n\n  }\n}\n\nmodule.exports = MochaRunner;\n"
  },
  {
    "path": "lib/runner/test-source.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst minimatch = require('minimatch');\nconst Utils = require('../utils');\nconst Concurrency = require('./concurrency');\nconst {Logger, validExtensions, jsFileExt, singleSourceFile} = Utils;\nconst {getTestSourceForRerunFailed} = require('./rerunUtil');\n\nclass TestSource {\n  static get GroupNameDelimiter() {\n    return ',';\n  }\n\n  constructor(settings, argv = {}) {\n    this.argv = argv;\n    this.settings = settings;\n    this.src_folders = settings.src_folders || [];\n  }\n\n  getTestSourceForSingle(targetPath) {\n    let testsource;\n\n    if (Array.isArray(targetPath)) {\n      targetPath = targetPath[0];\n    }\n\n    if (targetPath && path.resolve(targetPath) === targetPath) {\n      testsource = targetPath;\n    } else {\n      testsource = path.join(process.cwd(), targetPath);\n    }\n\n    const fileExt = path.parse(testsource).ext;\n\n    if (!validExtensions.includes(fileExt)) {\n      const fileExists = fs.existsSync(testsource);\n      if (fileExists) {\n        const err = new Error(`Cannot load file ${testsource}`);\n        err.detailedErr = `Files with ${fileExt} extension are not supported by Nightwatch.`;\n        err.showTrace = false;\n\n        throw err;\n      }\n\n      testsource += jsFileExt;\n    }\n\n    return testsource;\n  }\n\n  getRerunFailedFile(minimal_report_file_path) {\n    const jsonFile = path.resolve(process.env.NIGHTWATCH_RERUN_REPORT_FILE || minimal_report_file_path || '');\n\n    if (!Utils.fileExistsSync(jsonFile)) {\n      const err = new Error('Unable to find the Json reporter file to rerun failed tests');\n\n      err.showTrace = false;\n      err.detailedErr = 'Configure the environment variable NIGHTWATCH_RERUN_REPORT_FILE with Json reporter file path';\n      err.help = [\n        `Try setting ${Logger.colors.cyan('minimal_report_file_path: \"JSON-REPORTER-PATH\"')} in nightwatch configuration`,\n        `Or, try running: ${Logger.colors.cyan('export NIGHTWATCH_RERUN_REPORT_FILE=\"JSON-REPORTER-PATH\"')}`\n      ];\n\n      throw err;\n    }\n\n    return jsonFile;\n  }\n\n  getTestSourceForRerunFailed() {\n    const {reporter_options: {minimal_report_file_path}} = this.settings;\n    const minimalJsonFile = this.getRerunFailedFile(minimal_report_file_path);\n\n    try {\n      const {modules = {}} = require(minimalJsonFile);\n      const testsource = [];\n\n      Object.keys(modules).forEach(moduleKey => {\n        if (modules[moduleKey] && modules[moduleKey].status === 'fail') {\n          testsource.push(modules[moduleKey].modulePath);\n        }\n      });\n\n      if (testsource.length === 0) {\n        const err = new Error('Rerun Failed Tests: No failed tests found to rerun.');\n        err.noFailedTestFound = true;\n        err.showTrace = false;\n        err.detailedErr = 'Run nightwatch with --help to display usage info.';\n\n        throw err;\n      }\n\n      return testsource;\n    } catch (err) {\n      if (err.noFailedTestFound) {\n        err.message = 'Rerun Failed Tests: Invalid Json reporter.';\n\n        err.showTrace = false;\n        err.detailedErr = 'Please set env variable NIGHTWATCH_RERUN_REPORT_FILE with valid Json reporter path.';\n      }\n\n      throw err;\n    }\n  }\n\n  /**\n   * Returns the path where the tests are located\n   * @returns {*}\n   */\n  getSource() {\n    const {test_runner} = this.settings;\n\n    if ((process.env.NIGHTWATCH_RERUN_FAILED === 'true' || this.argv['rerun-failed']) && Concurrency.isMasterProcess() && test_runner?.type !== 'cucumber') {\n      return getTestSourceForRerunFailed(this.settings);\n    }\n\n    if (this.src_folders.length === 0 && test_runner?.src_folders && test_runner?.type === 'cucumber') {\n      this.src_folders = test_runner?.src_folders;\n    }\n\n    if (this.argv['test-worker'] || singleSourceFile(this.argv)) {\n      return this.getTestSourceForSingle(this.argv.test || this.argv._source);\n    }\n\n    if (this.argv.testcase) {\n      this.argv.testcase = null;\n\n      Logger.warn('Option --testcase used without --test is ignored.');\n    }\n\n    if (Array.isArray(this.argv._source) && (this.argv._source.length > 0)) {\n      return this.argv._source;\n    }\n\n    if (this.argv.group) {\n      // add support for multiple groups\n      if (Utils.isString(this.argv.group)) {\n        this.argv.group = this.argv.group.split(TestSource.GroupNameDelimiter);\n      }\n\n      const groupTestsource = this.findGroupPathMultiple(this.argv.group);\n\n      // If a group does not exist in the multiple src folder case, it is removed\n      // from the test path list.\n      if (this.src_folders.length === 1) {\n        return groupTestsource;\n      }\n      // only when all groups fail to match will there be a run error\n      const testsource = groupTestsource.filter(Utils.dirExistsSync);\n\n      if (!this.settings.silent) {\n        const ignoredSource = groupTestsource.filter(entry => testsource.indexOf(entry) === -1);\n\n        if (ignoredSource.length) {\n          Logger.warn('The following group paths were not found and will be excluded from the run:\\n - ' +\n            ignoredSource.join('\\n - '));\n        }\n      }\n\n      return testsource;\n    }\n\n    this.applySrcFilters();\n\n    return this.src_folders;\n  }\n\n  /**\n   * Apply \"exclude\" patterns on src_folders, in case more than one was specified\n   */\n  applySrcFilters() {\n    if (this.src_folders.length < 2) {\n      return this;\n    }\n\n    if (this.settings.exclude) {\n      const arrExclude = Array.isArray(this.settings.exclude) ? this.settings.exclude : [this.settings.exclude];\n      const resolvedExclude = arrExclude.map(item => path.resolve(item));\n\n      this.src_folders = this.src_folders.filter(item => {\n        const resolvedPath = path.resolve(item);\n        let match = true;\n\n        resolvedExclude.forEach(function(pattern) {\n          match = !resolvedPath.includes(pattern) && !minimatch(resolvedPath, pattern);\n        });\n\n        return match;\n      });\n    }\n  }\n\n  /**\n   * Gets test paths from each of the src folders for a single group.\n   *\n   * @param {string} groupName\n   * @return {Array}\n   */\n  findGroupPath(groupName) {\n    const fullGroupPath = path.resolve(groupName);\n\n    // for each src folder, append the group to the path\n    // to resolve the full test path\n\n    return this.src_folders.map(function(srcFolder) {\n      const fullSrcFolder = path.resolve(srcFolder);\n      if (fullGroupPath.indexOf(fullSrcFolder) === 0) {\n        return groupName;\n      }\n\n      return path.join(srcFolder, groupName);\n    });\n  }\n\n  /**\n   * Gets test paths for tests from any number of groups.\n   *\n   * @param {Array} groups\n   */\n  findGroupPathMultiple(groups) {\n    let paths = [];\n\n    groups.forEach(groupName => {\n      paths = paths.concat(this.findGroupPath(groupName));\n    });\n\n    return paths;\n  }\n}\n\nmodule.exports = TestSource;\n"
  },
  {
    "path": "lib/settings/defaults.js",
    "content": "const path = require('path');\nconst uuid = require('uuid');\n\nconst filename_format = function ({testSuite = '', testCase = '', isError = false, dateObject = new Date()} = {}) {\n  const fileName = [];\n  const dateParts = dateObject.toString().replace(/:/g, '').split(' ');\n  dateParts.shift();\n\n  const dateStamp = dateParts.slice(0, 5).join('-');\n  if (testSuite) {\n    fileName.push(testSuite);\n  }\n  if (testCase) {\n    fileName.push(testCase);\n  }\n\n  return `${fileName.join(path.sep)}${isError ? '_ERROR' : '_FAILED'}_${dateStamp}.png`;\n};\n\nconst snapshot_file_format = function({testSuite = '', testCase = '', commandName, dateObject = new Date()} = {}) {\n  const fileName = [];\n  const dateParts = dateObject.toString().replace(/:/g, '').split(' ');\n  dateParts.shift();\n\n  const dateStamp = dateParts.slice(0, 5).join('-');\n  if (testSuite) {\n    fileName.push(testSuite);\n  }\n  if (testCase) {\n    fileName.push(testCase);\n  }\n  if (commandName) {\n    fileName.push(commandName);\n  }\n\n  return `${fileName.join(path.sep)}_${dateStamp}.html`;\n};\n\nconst client_id = uuid.v4();\n\nmodule.exports = {\n  // Location(s) where custom commands will be loaded from.\n  custom_commands_path: null,\n\n  // Location(s) where custom assertions will be loaded from.\n  custom_assertions_path: null,\n\n  // Location(s) where page object files will be loaded from.\n  page_objects_path: null,\n\n  // An array specifying a list of Nightwatch plugin names that should be used; e.g.: plugins: ['vite-plugin-nightwatch']\n  plugins: [],\n\n  // Location of an external globals module which will be loaded and made available to the test as a\n  //  property globals on the main client instance.\n  globals_path: null,\n\n  // Location of the existing TypeScript config file. If not provided Nightwatch will search for \"nightwatch/tsconfig.json\" or \"tsconfig.nightwatch.json\".\n  tsconfig_path: '',\n\n  // An object which will be made available on the main test api, throughout the test execution\n  globals: {\n\n    // this controls whether to abort the test execution when an assertion failed and skip the rest\n    // it's being used in waitFor commands and expect assertions\n    abortOnAssertionFailure: true,\n\n    // this controls whether to abort the test execution when an element cannot be located; an error\n    // is logged in all cases, but this also enables skipping the rest of the testcase;\n    // it's being used in element commands such as .click() or .getText()\n    abortOnElementLocateError: false,\n\n    // this will overwrite the default polling interval (currently 500ms) for waitFor commands\n    // and expect assertions that use retry\n    waitForConditionPollInterval: 500,\n\n    // default timeout value in milliseconds for waitFor commands and implicit waitFor value for\n    // expect assertions\n    waitForConditionTimeout: 5000,\n\n    // this will cause waitFor commands on elements to throw an error if multiple\n    // elements are found using the given locate strategy and selector\n    throwOnMultipleElementsReturned: false,\n\n    // Since v2, the warning if multiple elements are found using the given locate strategy\n    // and selector is not shown by default anymore; set this to false to enable those warnings\n    suppressWarningsOnMultipleElementsReturned: true,\n\n    // controls the timeout value for async hooks. Expects the done() callback to be invoked within this time\n    // or an error is thrown\n    asyncHookTimeout: 20000,\n\n    // controls the timeout value for when running async unit tests. Expects the done() callback to be invoked within this time\n    // or an error is thrown\n    unitTestsTimeout: 2000,\n\n    // controls the timeout value for when executing the global async reporter. Expects the done() callback to be invoked within this time\n    // or an error is thrown\n    customReporterCallbackTimeout: 20000,\n\n    // Automatically retrying failed assertions - You can tell Nightwatch to automatically retry failed assertions until a given timeout is reached, before the test runner gives up and fails the test.\n    retryAssertionTimeout: 5000,\n\n    // use the same browser session to run the individual  test suites\n    reuseBrowserSession: false,\n\n    reporter: function(results, cb) {cb(results)},\n\n    beforeTestSuite(browser) {\n      return Promise.resolve();\n    },\n\n    afterTestSuite(browser) {\n      return Promise.resolve();\n    },\n\n    beforeTestCase(browser) {\n      return Promise.resolve();\n    },\n\n    afterTestCase(browser) {\n      return Promise.resolve();\n    },\n\n    onBrowserNavigate(browser) {\n      return Promise.resolve();\n    },\n\n    onBrowserQuit(browser) {\n      return Promise.resolve();\n    }\n  },\n\n  // configuration settings for the dotenv module - a zero-dependency module that loads environment variables from a .env file into process.env. More details on https://www.npmjs.com/package/dotenv\n  dotenv: {},\n\n  // persist the same globals object between runs or have a (deep) copy of it per each test;\n  // this can be useful when persisting data between test suites is needed, such as a cookie or session information\n  persist_globals: false,\n\n  reporter_options: {\n    // The location where the JUnit XML and HTML report files will be saved. Set this to false if you want to disable XML reporting\n    output_folder: 'tests_output',\n\n    //The folder formatting to use while saving HTML report\n    folder_format: null,\n\n    // The file name formatting to use while saving HTML report\n    filename_format: null,\n\n    minimal_report_file_path: 'tests_output/minimal_report.json',\n\n    // Save command result values in Json report (inline or in separate file).\n    save_command_result_value: false\n  },\n\n  // A string or array of folders (excluding subfolders) where the tests are located.\n  src_folders: null,\n\n  // Used when running in parallel to determine if the output should be collected and displayed at the end.\n  live_output: false,\n\n  // disable support of loading of typescript files for backwards compatibility with test suites\n  disable_typescript: false,\n\n  // Used to disable colored output in the terminal.\n  disable_colors: false,\n\n  // Used when running in parallel to specify the delay (in milliseconds) between starting the child processes\n  parallel_process_delay: 10,\n\n  // An object containing Selenium Server related configuration options\n  selenium: {\n    start_process: false,\n    cli_args: {},\n    server_path: null,\n    log_path: './logs',\n    port: undefined,\n    check_process_delay: 500,\n    max_status_poll_tries: 15,\n    status_poll_interval: 200\n  },\n\n  // Whether or not to automatically start the Selenium/WebDriver session. If running unit tests, this should be set tot false.\n  start_session: true,\n\n  // End the session automatically when the test is being terminated, usually after a failed assertion.\n  end_session_on_fail: true,\n\n  // Skip the remaining test cases from the current test suite, when one test case fails.\n  skip_testcases_on_fail: undefined,\n\n  // Whether or not to run individual test files in parallel.\n  test_workers: false,\n\n  /*\n  test_workers: {\n    enabled: true,\n\n    // automatically compute the number of workers based on CPU cores\n    workers: 'auto',\n\n    // manually specify the number of workers\n    workers: 4,\n\n    // pass node arguments to individual workers (all of the process.execArgv)\n    node_options: 'auto',\n\n    // selectively pass node arguments to individual worker processes\n    node_options: ['--inspect']\n  },\n  */\n\n  // Specifies which test runner to use: default|mocha\n  test_runner: 'default',\n\n  // Specifies which implementation to use for Concurrency: child-process|worker-threads\n  use_child_process: false,\n\n\n  // Defines options used to connect to the WebDriver/Selenium server\n  webdriver: {\n    start_process: false,\n    cli_args: {},\n    server_path: null,\n    log_path: './logs',\n\n    // leave empty to use the test suite name when writing the webdriver server logs\n    log_file_name: '',\n\n    // Time to wait (in ms) before starting to check the Webdriver server is up and running\n    check_process_delay: 100,\n\n    // Maximum number of ping status check attempts before returning a timeout error\n    max_status_poll_tries: 10,\n\n    // Interval (in ms) to use between status ping checks when checking if the Webdriver server is up and running\n    status_poll_interval: 200,\n\n    // The entire time (in ms) to wait for the Node.js process to be created and running (default is 2 min), including spawning the child process and checking the status\n    process_create_timeout: 120000,\n\n    host: undefined,\n    port: undefined,\n    ssl: undefined,\n    proxy: undefined,\n    timeout_options: {\n      timeout: 90000,\n      retry_attempts: 2\n    },\n    default_path_prefix: undefined,\n    username: undefined,\n    access_key: undefined\n  },\n\n  test_settings: {\n  },\n\n  // A url which can be used later in the tests as the main url to load.\n  launch_url: '',\n\n  // set to false if you want to show the extended http traffic command logs from the WebDriver server.\n  silent: true,\n\n  // Used to disable terminal output completely.\n  output: true,\n\n  // Set this to false if you'd like to only see the test case name displayed and pass/fail status.\n  detailed_output: true,\n\n  // Set this to true if you'd like to see timestamps next to the logging output\n  output_timestamp: false,\n\n  // Set this to true if you'd like to disable bounding boxes on terminal output. Useful when running in some CI environments.\n  disable_output_boxes: false,\n\n  // Set this to iso if you'd like to see timestamps as ISO strings\n  timestamp_format: '',\n\n  // Set this to true if you'd like to not display errors during the execution of the test (they are shown at the end always).\n  disable_error_log: false,\n\n  // By default, API command errors that don't deal with DOM elements (e.g. cookie) are ignored\n  report_command_errors: false,\n\n  // Ignore network errors (e.g. ECONNRESET errors)\n  report_network_errors: true,\n\n  // Interactive element commands such as \"click\" or \"setValue\" can be retried if an error occurred (such as an \"element not interactable\" error)\n  element_command_retries: 3,\n\n  // Take error and failure screenshots during test execution\n  screenshots: {\n    enabled: false,\n    filename_format,\n    path: '',\n    on_error: true,\n    on_failure: true\n  },\n\n  trace: {\n    enabled: false,\n    path: '',\n    filename_format: snapshot_file_format\n  },\n\n  // Used to enable showing the Base64 image data in the (verbose) log when taking screenshots.\n  log_screenshot_data: false,\n\n  desiredCapabilities: {\n    browserName: 'firefox'\n  },\n\n  // An array of folders or file patterns to be skipped (relative to the main source folder).\n  exclude: null,\n\n  // Folder or file pattern to be used when loading the tests. Files that don't match this pattern will be ignored.\n  filter: null,\n\n  // Skip a group of tests (a subfolder); can be a list of comma-separated values (no space)\n  skipgroup: '',\n\n  sync_test_names: true,\n\n  // Skip tests by tag name; can be a list of comma-separated values (no space)\n  skiptags: '',\n\n  // Use xpath as the default locator strategy\n  use_xpath: false,\n\n  parallel_mode: false,\n\n  report_prefix: '',\n\n  unit_testing_mode: false,\n\n  default_reporter: ['junit', 'json', 'minimalJson', 'html'],\n\n  // In Nightwatch v1.x, when used with \"await\" operator, API commands will return the full result object as {value: `<VALUE>`}\n  // whereas in v2, the value is return directly; if using a callback, the behaviour remains unchanged\n  backwards_compatibility_mode: false,\n\n  // disable the global apis like \"browser\", \"element()\", \"expect()\"; this might be needed if using Nightwatch with third-party libraries\n  disable_global_apis: false,\n\n  // disable only the global expect\n  disable_global_expect: false,\n\n  // enable aborting the test run execution when the first test failure occurs; the remaining test suites will be skipped\n  enable_fail_fast: false,\n\n  always_async_commands: false,\n\n  enable_v3_element_apis: true,\n\n  usage_analytics: {\n    enabled: false,\n    log_path: './logs/analytics',\n    client_id\n  }\n};\n"
  },
  {
    "path": "lib/settings/settings.js",
    "content": "const dotenv = require('dotenv');\nconst path = require('path');\nconst defaultsDeep = require('lodash/defaultsDeep');\nconst lodashCloneDeep = require('lodash/cloneDeep');\nconst lodashMerge = require('lodash/merge');\nconst CI_Info = require('ci-info');\nconst Defaults = require('./defaults.js');\nconst Utils = require('../utils');\nconst {isObject, isUndefined, isDefined, isNumber, singleSourceFile} = Utils;\n\nclass Settings {\n\n  static get DEFAULT_ENV() {\n    return 'default';\n  }\n\n  static get DEFAULTS() {\n    return Defaults;\n  }\n\n  /**\n   * Looks for pattern ${VAR_NAME} in settings\n   * @param {Object} [target]\n   */\n  static replaceEnvVariables(target) {\n    for (const key in target) {\n      switch (typeof target[key]) {\n        case 'object':\n          Settings.replaceEnvVariables(target[key]);\n          break;\n\n        case 'string':\n          target[key] = target[key].replace(/\\${(\\w+)\\|?([^}]*)}/, function(match, varName, defaultValue) {\n            return process.env[varName] || defaultValue || '${' + varName + '}';\n          });\n          break;\n      }\n    }\n\n    return this;\n  }\n\n  static getDefaults() {\n    return lodashCloneDeep(Settings.DEFAULTS);\n  }\n\n  /**\n   * Called from the cli runner with data from config file\n   *\n   * @param {Object} [settings] additional settings which can be passed when called programmatically\n   * @param {Object} [baseSettings] settings data from nightwatch config file\n   * @param {Object} [argv] cli arguments object\n   * @param {String} [testEnv] current test environment\n   * @returns {Object}\n   */\n  static parse(settings = {}, baseSettings = {}, argv = {}, testEnv = '') {\n    const instance = new Settings(argv, testEnv);\n    instance.fromConfigFile(baseSettings);\n    instance.inheritFromDefaultEnv();\n    instance.init(settings);\n\n    return instance.settings;\n  }\n\n  /**\n   * Called from Nightwatch main client instance containing either an existing settings object or a new one\n   *\n   * @param {Object} userSettings\n   * @param {Object} argv\n   * @returns {Object}\n   */\n  static fromClient(userSettings = {}, argv = {}) {\n    const instance = new Settings(argv);\n    instance.init(userSettings);\n\n    return instance.settings;\n  }\n\n  static isNightwatchObject(settings) {\n    return isDefined(settings['[[@nightwatch_createdAt]]']);\n  }\n\n  /**\n   * @deprecated\n   * @param settings\n   */\n  static setDefaults(settings) {\n    defaultsDeep(settings, Defaults);\n\n    if (settings.unit_testing_mode) {\n      settings.unit_tests_mode = true;\n    }\n\n    if (!settings.unit_tests_mode) {\n      settings.skip_testcases_on_fail = settings.skip_testcases_on_fail || isUndefined(settings.skip_testcases_on_fail);\n    }\n  }\n\n  static isUsingSeleniumServer(settings) {\n    return settings.selenium && settings.selenium.start_process;\n  }\n\n  get testWorkersEnabled() {\n    const {test_workers} = this.settings;\n    const {serial, debug, parallel} = this.argv;\n\n    if (serial || debug) {\n      return false;\n    }\n\n    if (parallel || test_workers === true) {\n      return true;\n    }\n\n    if (test_workers && test_workers.enabled && (test_workers.workers === 'auto' || test_workers.workers > 1)) {\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * @param {Object} [argv] the cli arguments object\n   * @param {String} [testEnv] the current test env\n   */\n  constructor(argv = {}, testEnv = '') {\n    this.baseSettings = null;\n    this.argv = argv;\n    this.testEnv = testEnv || '';\n\n    this.initSettingsObject();\n  }\n\n  /**\n   * @param {Object|null} [baseSettings] the raw nightwatch config object\n   * @param baseSettings\n   */\n  fromConfigFile(baseSettings) {\n    this.baseSettings = baseSettings || {};\n    this.copyGenericProperties();\n  }\n\n  /**\n   * Initialize a new settings object based on the defaults\n   */\n  initSettingsObject() {\n    this.settings = Settings.getDefaults();\n    this.settings.testEnv = this.testEnv;\n  }\n\n  /**\n   * Copy all properties from the config file to this.settings that are located outside any test environment\n   *  defined as part of the \"test_settings\" dictionary;\n   *\n   * This allows to define non-standard properties to the Nightwatch settings object\n   */\n  copyGenericProperties() {\n    Object.keys(this.baseSettings).forEach(key => {\n      if (key === 'test_settings') {\n        return;\n      }\n\n      const copyVal = lodashCloneDeep(this.baseSettings[key]);\n\n      if (isObject(this.settings[key])) {\n        Object.assign(this.settings[key], copyVal);\n      } else {\n        this.settings[key] = copyVal;\n      }\n    });\n  }\n\n  isSettingsDefined(settingName) {\n    const {webdriver} = this.settings;\n\n    if (isObject(webdriver[settingName])) {\n      const values = Object.values(webdriver[settingName]);\n\n      return values.every(item => isDefined(item));\n    }\n\n    return isDefined(webdriver[settingName]);\n  }\n  /**\n   * Tries to set a webdriver setting from a several legacy places if the value is not already set\n   *\n   * @param {String} newSetting the new property name\n   * @param {String|Array} [oldSetting]\n   * @param {Object} [opts]\n   * @returns {Settings} for chaining\n   */\n  setWebdriverHttpOption(newSetting, oldSetting, opts = {}) {\n    const webdriverOpts = this.settings.webdriver;\n\n    if (this.isSettingsDefined(newSetting)) {\n      return this;\n    }\n\n    if (oldSetting === undefined) {\n      oldSetting = [newSetting];\n    } else if (!Array.isArray(oldSetting)) {\n      oldSetting = [oldSetting];\n    }\n\n    for (let i = 0; i < oldSetting.length; i++) {\n      const item = oldSetting[i];\n      if (isDefined(this.settings[item])) {\n        webdriverOpts[newSetting] = this.settings[item];\n\n        return this;\n      }\n    }\n\n    if (isDefined(opts.defaultValue)) {\n      webdriverOpts[newSetting] = opts.defaultValue;\n    }\n\n    return this;\n  }\n\n  isUsingSelenium() {\n    const {selenium} = this.settings;\n\n    return isObject(selenium);\n  }\n\n  isSeleniumServerManaged() {\n    return this.isUsingSelenium() && this.settings.selenium.start_process;\n  }\n\n  /**\n   * Set the connection settings to the Webdriver server and any networking options\n   */\n  setWebdriverSettings() {\n    // if using selenium server, we read settings from the selenium dictionary\n    if (this.isSeleniumServerManaged()) {\n      lodashMerge(this.settings.webdriver, this.settings.selenium);\n    } else if (this.isUsingSelenium()) {\n      defaultsDeep(this.settings.webdriver, this.settings.selenium);\n    }\n\n    this\n      .setWebdriverHttpOption('host', ['seleniumHost', 'selenium_host'], {defaultValue: 'localhost'})\n      .setWebdriverHttpOption('port', ['seleniumPort', 'selenium_port'])\n      .setWebdriverHttpOption('ssl', ['useSsl', 'use_ssl'])\n      .setWebdriverHttpOption('proxy')\n      .setWebdriverHttpOption('start_session')\n      .setWebdriverHttpOption('timeout_options', 'request_timeout_options')\n      .setWebdriverHttpOption('default_path_prefix')\n      .setWebdriverHttpOption('username')\n      .setWebdriverHttpOption('access_key', ['accessKey', 'access_key', 'password']);\n\n    if (isUndefined(this.settings.webdriver.ssl)) {\n      this.settings.webdriver.ssl = this.settings.webdriver.port === 443;\n    }\n\n    if (!this.settings.webdriver.host) {\n      this.settings.webdriver.host = this.settings.selenium_host || 'localhost';\n    }\n\n    this.setServerUrl();\n  }\n\n  /**\n   * Set the webdriver server url which will be used in case the service is not managed by Nightwatch\n   */\n  setServerUrl() {\n    const protocol = this.settings.webdriver.ssl ? 'https' : 'http';\n    const {port, host, default_path_prefix = ''} = this.settings.webdriver;\n    this.settings.webdriver.url = `${protocol}://${host}:${port}${default_path_prefix}`;\n\n    if (isObject(this.settings.selenium)) {\n      this.settings.selenium.url = this.settings.webdriver.url;\n    }\n  }\n\n  mergeOntoExisting(userSettings = {}) {\n    lodashMerge(this.settings, userSettings);\n\n    return this;\n  }\n\n  /**\n   * @returns {Settings}\n   */\n  adaptSettings() {\n    this.setCliOptions();\n    this.setScreenshotsOptions();\n    this.setUnitTestsMode();\n    this.setParallelMode();\n    this.setTestRunner();\n    this.setReporterOptions();\n\n    if (typeof this.settings.src_folders == 'string') {\n      this.settings.src_folders = [this.settings.src_folders];\n    }\n\n    if (typeof this.settings.skipgroup == 'string' && this.settings.skipgroup.length > 0) {\n      this.settings.skipgroup = this.settings.skipgroup.split(',');\n    }\n\n    return this;\n  }\n\n  setReporterOptions() {\n    defaultsDeep(this.settings, this.settings.reporter_options);\n\n    if (this.argv.trace === true) {\n      this.settings.trace.enabled = true;\n    }\n  }\n\n  setParallelMode() {\n    const Concurrency = require('../runner/concurrency');\n\n    if (Concurrency.isWorker()) {\n      this.settings.parallel_mode = true;\n    }\n\n    if (isObject(this.settings.test_workers)) {\n      this.settings.test_workers.workers = this.settings.test_workers.workers || 'auto';\n    }\n\n    if (this.argv.parallel === true && !this.settings.test_workers) {\n      this.settings.test_workers = true;\n    } else if (isNumber(this.argv.parallel)) {\n      if (!isObject(this.settings.test_workers)) {\n        this.settings.test_workers = {\n          enabled: true\n        };\n      }\n\n      this.settings.test_workers.workers = this.argv.parallel || this.settings.test_workers.workers;\n    } else if (isNumber(this.argv.workers)) {\n      if (!isObject(this.settings.test_workers)) {\n        this.settings.test_workers = {\n          enabled: true\n        };\n      }\n\n      this.settings.test_workers.workers = this.argv.workers || this.settings.test_workers.workers;\n    }\n\n    this.settings.testWorkersEnabled = this.testWorkersEnabled && (!singleSourceFile(this.argv) || this.argv['test-worker'] === true);\n\n    return this;\n  }\n\n  setTestRunner() {\n    if (Utils.isString(this.settings.test_runner)) {\n      this.settings.test_runner = {\n        type: this.settings.test_runner,\n        options: {}\n      };\n    } if (!Utils.isObject(this.settings.test_runner)) {\n      throw new Error(`Invalid \"test_runner\" settings specified; received: ${this.settings.test_runner}`);\n    }\n\n    return this;\n  }\n\n  setUnitTestsMode() {\n    const unitTesting = this.settings.unit_tests_mode || this.settings.unit_testing_mode;\n\n    this.settings.unit_testing_mode = this.settings.unit_tests_mode = unitTesting;\n\n    if (unitTesting) {\n      this.settings.webdriver.start_process = false;\n      this.settings.webdriver.start_session = false;\n      this.settings.start_session = false;\n      this.settings.detailed_output = false;\n      this.settings.output_timestamp = false;\n    } else {\n      this.settings.skip_testcases_on_fail = this.settings.skip_testcases_on_fail || isUndefined(this.settings.skip_testcases_on_fail);\n    }\n\n    return this;\n  }\n\n  inheritFromDefaultEnv() {\n    if (!this.baseSettings.test_settings) {\n      return this;\n    }\n\n    const defaultEnvSettings = this.baseSettings.test_settings[Settings.DEFAULT_ENV] || {};\n    lodashMerge(this.settings, defaultEnvSettings);\n\n    if (!this.testEnv || this.testEnv === Settings.DEFAULT_ENV) {\n      return this;\n    }\n\n    const testEnvSettings = this.baseSettings.test_settings[this.testEnv] || {};\n    this.inheritFromSuperEnv(testEnvSettings);\n    defaultsDeep(testEnvSettings, defaultEnvSettings);\n    lodashMerge(this.settings, testEnvSettings);\n\n    return this;\n  }\n\n  inheritFromSuperEnv(testEnvSettings) {\n    if (testEnvSettings.extends) {\n      const superEnv = this.baseSettings.test_settings[testEnvSettings.extends] || {};\n      delete testEnvSettings.extends;\n      defaultsDeep(testEnvSettings, superEnv);\n\n      return this.inheritFromSuperEnv(testEnvSettings);\n    }\n\n    return testEnvSettings;\n  }\n\n  /**\n   * @param settings\n   */\n  persistGlobals(settings) {\n    if (this.settings.persist_globals === true && isObject(settings.globals)) {\n      defaultsDeep(settings.globals, this.settings.globals);\n      this.settings.globals = settings.globals;\n    }\n  }\n\n  setScreenshotsOptions() {\n    if (isObject(this.settings.screenshots)) {\n      this.settings.screenshots.path = this.settings.screenshots.path ? path.resolve(this.settings.screenshots.path) : '';\n    } else {\n      const enabled = this.settings.screenshots === true;\n      this.settings.screenshots = Object.assign({}, Defaults.screenshots, {enabled});\n    }\n\n    this.settings.screenshotsPath = this.settings.screenshots.path;\n\n    return this;\n  }\n\n  setCliOptions() {\n    if (this.argv.verbose) {\n      this.settings.silent = false;\n    }\n\n    const cliOverwrites = {\n      output_folder: this.argv.output,\n      filename_filter: this.argv.filter,\n      tag_filter: this.argv.tag,\n      skipgroup: this.argv.skipgroup,\n      skiptags: this.argv.skiptags,\n      enable_fail_fast: this.argv['fail-fast']\n    };\n\n    Object.keys(cliOverwrites).forEach(key => {\n      if (isDefined(cliOverwrites[key]) && cliOverwrites[key] !== null) {\n        this.settings[key] = cliOverwrites[key];\n      }\n    });\n\n    // TODO: add support for overwriting any setting\n\n    return this;\n  }\n\n  sortSettings() {\n    const sortedSettings = {};\n    Object.keys(this.settings).sort().forEach(key => {\n      sortedSettings[key] = this.settings[key];\n    });\n\n    this.settings = sortedSettings;\n\n    Object.defineProperty(this.settings, '[[@nightwatch_createdAt]]', {\n      value: new Date().valueOf(),\n      enumerable: false,\n      configurable: false,\n      writable: false\n    });\n  }\n\n  setBaseUrl() {\n    const value = this.settings.baseUrl || this.settings.base_url || this.settings.launchUrl || this.settings.launch_url || null;\n\n    if (value) {\n      this.settings.baseUrl =\n        this.settings.base_url =\n        this.settings.launchUrl =\n        this.settings.launch_url = value;\n    }\n  }\n\n  setColorOutput() {\n    const {isCI, CIRCLE, JENKINS, NETLIFY, TRAVIS, GITLAB, GITHUB_ACTIONS, BUILDKITE} = CI_Info;\n    const coloringSupport = CIRCLE || JENKINS || NETLIFY || TRAVIS || GITLAB || BUILDKITE || GITHUB_ACTIONS;\n\n    if (isCI && !coloringSupport) {\n      this.settings.disable_colors = true;\n    }\n  }\n\n  /**\n   * Validates and parses the test settings\n   *\n   * @param {Object} [userSettings]\n   */\n  init(userSettings = {}) {\n    this.mergeOntoExisting(userSettings);\n    this.setWebdriverSettings();\n\n    this.adaptSettings();\n    this.sortSettings();\n\n    this.persistGlobals(userSettings);\n\n    dotenv.config(this.settings.dotenv);\n    Settings.replaceEnvVariables(this.settings);\n\n    this.setBaseUrl();\n    this.setColorOutput();\n  }\n}\n\nmodule.exports = Settings;\n"
  },
  {
    "path": "lib/testsuite/context.js",
    "content": "const path = require('path');\nconst EventEmitter = require('events');\nconst Utils = require('../utils');\n\nconst ExportsInterface = require('./interfaces/exports.js');\nconst DescribeInterface = require('./interfaces/describe.js');\n\nclass Context extends EventEmitter {\n  static get REPORT_KEY_SEPARATOR() {\n    return path.sep;\n  }\n\n  get isTestHook() {\n    return false;\n  }\n\n  constructor({modulePath, settings, argv = {}, attributes = {}}) {\n    super();\n    this.settings = settings;\n    this.argv = argv;\n\n    this.__module = null;\n    this.__testsuite = {};\n    this.__currentRunnable = null;\n    this.__retries = {\n      testcase: null,\n      suite: null\n    };\n    this.attributes = attributes;\n    this.groupName = '';\n\n    if (modulePath) {\n      this.setModulePath(modulePath);\n    }\n  }\n\n  setModulePath(file) {\n    this.modulePath = file;\n    this.__moduleName = path.parse(this.modulePath).name;\n    this.moduleKey = this.moduleName || '';\n  }\n\n  loadTags({usingMocha = false} = {}) {\n    if (!usingMocha) {\n      return;\n    }\n\n    const context = this;\n    const {Suite} = require('mocha');\n    class BasicSuite extends Suite {\n      get tags() {\n        return context.attributes['@tags'];\n      }\n\n      set tags(value) {\n        context.attributes['@tags'] = value;\n      }\n    }\n\n    global.describe = function(title, definitionFn) {\n      const instance = new BasicSuite(title);\n\n      definitionFn.call(instance);\n    };\n\n    try {\n      this.__module = this.requireModule(this.modulePath); // eslint-disable-next-line no-empty\n    } catch (err) {}\n  }\n\n  async init({usingMocha = false, suiteTitle = null, client = null} = {}) {\n    this.__currentTestName = this.argv.testcase;\n    this.__testSuiteName = suiteTitle;\n\n    this.__hooks = [];\n    this.__testcases = [];\n    this.__skippedTestCases = [];\n    this.__allScreenedTests = [];\n    this.__contextBinding = {};\n\n    this.__transforms = client ? await client.transforms : [];\n\n\n    this.source = this.argv._source || [];\n\n    if (!usingMocha) {\n      this.createInterface(client);\n      await this.loadModule();\n    }\n\n    this.createTestSuite();\n\n    return this;\n  }\n\n  get testSuiteName() {\n    return this.__testSuiteName;\n  }\n\n  get currentTest() {\n    return this.__currentTestName;\n  }\n\n  get contextBinding() {\n    return this.__contextBinding;\n  }\n\n  /**\n   * @returns {boolean}\n   */\n  get unitTestingMode() {\n    return this.settings.unit_testing_mode || this.isUnitTest();\n  }\n\n  /**\n   * @deprecated\n   * @returns {boolean}\n   */\n  get unitTestsMode() {\n    return this.settings.unit_tests_mode || this.isUnitTest();\n  }\n\n  get moduleName() {\n    return this.__moduleName;\n  }\n\n  get module() {\n    return this.__module;\n  }\n\n  get testsuite() {\n    return this.__testsuite;\n  }\n\n  get tests() {\n    return this.__testcases;\n  }\n\n  set tests(value) {\n    this.__testcases = value;\n  }\n\n  get skippedTests() {\n    return this.__skippedTestCases;\n  }\n\n  set skippedTests(value) {\n    this.__skippedTestCases = value;\n  }\n\n  get allScreenedTests() {\n    return this.__allScreenedTests;\n  }\n\n  set allScreenedTests(value) {\n    this.__allScreenedTests = value;\n  }\n\n  get hooks() {\n    return this.__hooks;\n  }\n\n  get currentRunnable() {\n    return this.__currentRunnable;\n  }\n\n  get queue() {\n    return this.currentRunnable && this.currentRunnable.queue;\n  }\n\n  get queueStarted() {\n    return this.queue && this.queue.started;\n  }\n\n  get retries() {\n    return this.__retries;\n  }\n\n  setReloadModuleCache(val = true) {\n    this.__reloadModuleCache = val;\n\n    return this;\n  }\n\n  shouldReloadModuleCache() {\n    return this.__reloadModuleCache;\n  }\n\n  get usingBddDescribe() {\n    return this.bddInterface && Utils.isFunction(this.bddInterface.describeFn);\n  }\n\n  getName() {\n    return this.moduleName;\n  }\n\n  getSuiteName() {\n    return this.testSuiteName || Utils.getTestSuiteName(this.moduleKey);\n  }\n\n  setCurrentRunnable(runnable) {\n    this.__currentRunnable = runnable;\n\n    return this;\n  }\n\n  createInterface(client) {\n    this.exportsInterface = new ExportsInterface(this);\n    this.bddInterface = new DescribeInterface(this, client);\n\n    return this;\n  }\n\n  async loadModule() {\n    this.emit('pre-require', global);\n\n    this.__module = await this.requireModule();\n\n    if (!this.module && !this.bddInterface.describeFn) {\n      throw new Error(`Empty module provided in: \"${this.modulePath}\".`);\n    }\n\n    if (this.module) {\n      this.__testsuite = Object.assign(this.__testsuite, this.module);\n    }\n\n    this.emit('post-require');\n    this.emit('module-loaded');\n\n    return this;\n  }\n\n  async requireModule(loadJsWithPlugins = false) {\n    const pluginDescriptor = this.__transforms.find(transform => {\n      const {filter} = transform;\n\n      if (Utils.isFunction(filter)) {\n        return filter(this.modulePath, loadJsWithPlugins);\n      }\n\n      return filter.test(this.modulePath);\n    });\n\n    if (pluginDescriptor) {\n      try {\n        const testContext = await pluginDescriptor.requireTest(this.modulePath, pluginDescriptor, {\n          argv: this.argv,\n          nightwatch_settings: this.settings\n        });\n\n        if (testContext && testContext.initialize) {\n          return testContext;\n        }\n\n        return {};\n      } catch (err) {\n        const error = new Error(`Error while trying to load ${this.modulePath}`);\n        error.detailedErr = err.message;\n        error.stack = err.stack;\n\n        throw error;\n      }\n    }\n\n    try {\n      return Utils.requireModule(this.modulePath);\n    } catch (err) {\n      if ((err instanceof SyntaxError) && !loadJsWithPlugins) {\n        return await this.requireModule(true);\n      }\n\n      throw err;\n    }\n  }\n\n  createTestSuite() {\n    if (this.currentTest && this.tests.length === 0) {\n      throw new Error(`\"${this.currentTest}\" is not a valid testcase in the current test suite.`);\n    }\n\n    if (this.currentTest && this.tests.length > 1) {\n      this.tests = [this.currentTest];\n    }\n    this.__moduleKeysCopy = this.tests.slice(0);\n  }\n\n  addTestSuiteMethod(testName, testFn, context) {\n    this.testsuite[testName] = testFn;\n    this.contextBinding[testName] = context || this.module;\n  }\n\n  /**\n   * Add test hooks created by describe interface\n   *\n   * @param {string} hookName\n   * @param {Function} hookFn\n   * @param {Object} [context]\n   */\n  addTestHook(hookName, hookFn, context) {\n    // TODO: warn if hook name already exists\n    this.hooks.push(hookName);\n    this.addTestSuiteMethod(hookName, hookFn, context);\n  }\n\n  /**\n   * Add testcases created by describe interface\n   *\n   * @param {string} testName\n   * @param {function} testFn\n   * @param {Object} [describeInstance] The instance of the describe function declaration\n   * @param {Boolean=false} [runOnly] If the runner should run only this testcase\n   * @param {Boolean=false} [skipTest] If the testcase should be skipped\n   */\n  addTestCase({testName, testFn, describeInstance, runOnly, skipTest}) {\n    if (!Utils.isFunction(testFn)) {\n      throw new Error(`The \"${testName}\" test script must be a function. \"${typeof testFn}\" given.`);\n    }\n\n    if (this.allScreenedTests.includes(testName)) {\n      const {Logger} = Utils;\n\n      const err = new Error(\n        'An error occurred while loading the testsuite:\\n' +\n        `A testcase with name \"${testName}\" already exists. Testcases must have unique names inside the test suite, ` +\n        'otherwise testcases with duplicate names might not run at all.\\n\\n' +\n        'This testsuite has been disabled, please fix the error to run it again properly.'\n      );\n      Logger.error(err);\n\n      this.setAttribute('@disabled', true);\n    }\n\n    if (!skipTest) {\n      this.tests.push(testName);\n    } else {\n      this.skippedTests.push(testName);\n    }\n\n    this.addTestSuiteMethod(testName, testFn, describeInstance);\n    if (runOnly) {\n      this.__currentTestName = testName;\n      this.skippedTests = [...this.allScreenedTests];\n      this.runOnly = true;\n    } else if (this.runOnly) {\n      this.skippedTests.push(testName);\n    }\n\n    this.allScreenedTests.push(testName);\n  }\n\n  /**\n   * Create a testsuite using describe interface\n   *\n   * @param {string} describeTitle\n   * @param {Object} describeInstance The instance of the describe function declaration\n   * @param {Boolean=false} [runOnly] If the runner should run only this testsuite\n   */\n  setDescribeContext({describeTitle, describeInstance, runOnly}) {\n    // if `setDescribeContext` is called twice for the same test suite,\n    // that would mean that there are two `describe()`s in same test suite.\n    if (this.__testSuiteName && describeInstance) {\n      // eslint-disable-next-line no-console\n      console.warn(\n        'Nightwatch does not support more than one \"describe\" declarations in a single testsuite.' +\n        ' Using this might give unexpected results.'\n      );\n    }\n\n    if (runOnly) {\n      // eslint-disable-next-line no-console\n      console.warn('describe.only() is not supported at the moment.');\n    }\n\n    this.__testSuiteName = describeTitle;\n  }\n\n  setTestcaseRetries(n) {\n    this.retries.testcase = n;\n  }\n\n  setSuiteRetries(n) {\n    this.retries.suite = n;\n  }\n  ////////////////////////////////////////////////////////////////\n  // Attributes\n  ////////////////////////////////////////////////////////////////\n  isES6Async(testName) {\n    return Utils.isES6AsyncFn(this.testsuite[testName]);\n  }\n\n  addAttributes(attributes = {}) {\n    Object.assign(this.attributes, attributes);\n  }\n\n  setAttribute(name, value) {\n    this.attributes[name] = value;\n  }\n\n  getAttribute(name) {\n    return this.attributes[name];\n  }\n\n  isDisabled() {\n    return this.attributes['@disabled'] === true;\n  }\n\n  isUnitTest() {\n    return this.attributes['@unitTest'] === true;\n  }\n\n  getSkipTestcasesOnFail() {\n    return this.attributes['@skipTestcasesOnFail'];\n  }\n\n  getEndSessionOnFail() {\n    return this.attributes['@endSessionOnFail'];\n  }\n\n  getNameAttr() {\n    return this.attributes['@name'];\n  }\n\n  getTags() {\n    return this.attributes['@tags'];\n  }\n\n  getDesiredCapabilities() {\n    return this.attributes['@desiredCapabilities'];\n  }\n\n  ////////////////////////////////////////////////////////////////\n  // Module calls\n  ////////////////////////////////////////////////////////////////\n  /**\n   *\n   * @param {function} done\n   * @param {Object} api\n   * @param {Number} expectedArgs\n   * @return []\n   */\n  getHookFnArgs(done, api, expectedArgs) {\n    if (this.unitTestsMode) {\n      return [done];\n    }\n\n    const args = [api];\n    if (expectedArgs === 2) {\n      args.push(done);\n    }\n\n    return args;\n  }\n\n  extendContextWithApi(context, api) {\n    if (('client' in context) && this.modulePath &&\n        context.client && !('currentTest' in context.client)) {\n      throw new Error('There is already a .client property defined in: ' + this.modulePath);\n    }\n\n    context.client = api;\n  }\n\n  /**\n   *\n   * @param {string} fnName\n   * @param {Object} client\n   * @param {Number} expectedArgs\n   * @param {function} done\n   * @return {*}\n   */\n  invokeMethod(fnName, client, expectedArgs, done) {\n    const isES6Async = this.isES6Async(fnName);\n    const isTestHook = this.isTestHook;\n\n    if (client) {\n      client.isES6AsyncTestcase = isES6Async;\n      client.isES6AsyncTestHook = isTestHook ? isES6Async : undefined;\n    }\n\n    const api = client && client.api || null;\n    let context;\n    if (this.contextBinding && this.contextBinding[fnName]) {\n      context = this.contextBinding[fnName];\n    } else {\n      context = this.__module;\n    }\n\n    this.extendContextWithApi(context, api);\n\n    switch (expectedArgs) {\n      case 2:\n      case 1:\n        return this.callAsync({fnName, api, expectedArgs, done, context, isES6Async, isTestHook});\n\n      case 0: {\n        try {\n          const result = this.call(fnName);\n          if (!(result instanceof Promise)) {\n            return done();\n          }\n\n          result.then(() => {\n            done();\n          }).catch(err => {\n            done(err);\n          });\n        } catch (err) {\n          done(err);\n        }\n      }\n    }\n  }\n\n  /**\n   * @param {string} fnName\n   * @param {Array} args\n   */\n  call(fnName, ...args) {\n    const context = this.contextBinding[fnName];\n    const client = args[0];\n    if (client) {\n      const isES6Async = this.isES6Async(fnName);\n      client.isES6AsyncTestcase = isES6Async;\n      client.isES6AsyncTestHook = this.isTestHook ? isES6Async : undefined;\n      args[0] = client.api;\n    }\n\n    const result = this.testsuite[fnName].apply(context, args);\n    if (this.currentRunnable) {\n      this.currentRunnable.currentTestCaseResult = result;\n    }\n\n    return result;\n  }\n\n  /**\n   *\n   * @param {string} fnName\n   * @param {Object} api\n   * @param {Number} expectedArgs\n   * @param {function} done\n   * @param {Object} context\n   * @return {*}\n   */\n  callAsync({fnName, api, expectedArgs = 2, done = function() {}, context}) {\n    const fnAsync = Utils.makeFnAsync(expectedArgs, this.testsuite[fnName], context);\n    const args = this.getHookFnArgs(done, api, expectedArgs);\n\n    const result = fnAsync.apply(context, args);\n    if (this.currentRunnable) {\n      this.currentRunnable.currentTestCaseResult = result;\n    }\n\n    return result;\n  }\n\n  ////////////////////////////////////////////////////////////////\n  // Module keys\n  ////////////////////////////////////////////////////////////////\n  hasHook(key) {\n    return this.hooks.indexOf(key) > -1;\n  }\n\n  getKey(key) {\n    return this.testsuite[key];\n  }\n\n  getNextKey() {\n    if (this.tests.length) {\n      return this.tests.shift();\n    }\n\n    return null;\n  }\n\n  /**\n   * When using retries, the testcases are reset\n   *\n   * @return {Context}\n   */\n  reset() {\n    this.tests = this.__moduleKeysCopy.slice();\n\n    return this;\n  }\n\n  ////////////////////////////////////////////////////////////////\n  // Reporting\n  ////////////////////////////////////////////////////////////////\n  setReportKey(allModulePaths = []) {\n    if (!this.modulePath) {\n      return;\n    }\n\n    let parentFolder = this.modulePath.substring(0, this.modulePath.lastIndexOf(path.sep));\n    const parentFolderName = parentFolder.split(path.sep).pop();\n    const srcFolders = this.settings.src_folders || this.source || [];\n\n    let diffInFolder = '';\n\n    if (srcFolders.length > 0) {\n      for (let i = 0; i < srcFolders.length; i++) {\n        const srcPathResolved = path.resolve(srcFolders[i]);\n        diffInFolder = this.getDiffFromSourceFolder(srcPathResolved, parentFolder, srcFolders);\n\n        if (diffInFolder) {\n          this.moduleKey = [diffInFolder, this.moduleKey].join(Context.REPORT_KEY_SEPARATOR);\n          this.groupName = parentFolderName;\n          parentFolder = parentFolder.substring(0, parentFolder.lastIndexOf(path.sep + diffInFolder)); // removing the diffInFolder string from the parent folder\n          break;\n        }\n      }\n    }\n\n    // in case we're using src_folders and there are more than one, prepend the parent folder name to the report key\n    if (diffInFolder === '' && Array.isArray(this.settings.src_folders) && this.settings.src_folders.length > 1) {\n      this.moduleKey = [parentFolderName, this.moduleKey].join(Context.REPORT_KEY_SEPARATOR);\n    }\n\n    // in case there are several test files, make sure the report key is unique\n    if (allModulePaths.length > 1) {\n      this.moduleKey = this.checkKeyForUniqueness(allModulePaths, parentFolder);\n    }\n  }\n\n  shouldCheckIfDirectory() {\n    return !this.settings.src_folders && this.source.length > 1;\n  }\n\n  checkKeyForUniqueness(allModulePaths, parentFolder) {\n    // removing the current module\n    const modulePathsCopy = allModulePaths.slice(0);\n    const index = modulePathsCopy.indexOf(this.modulePath);\n\n    if (index > -1) {\n      modulePathsCopy.splice(index, 1);\n    }\n\n    const modulePathParts = parentFolder.split(path.sep);\n\n    return this.getUniqueModuleKey(modulePathsCopy, modulePathParts, this.moduleKey);\n  }\n\n  /**\n   *\n   * @param {string} srcPathResolved\n   * @param {string} moduleParentFolder\n   * @param {Array} source\n   */\n  getDiffFromSourceFolder(srcPathResolved, moduleParentFolder, source) {\n    const isDirectory = !this.shouldCheckIfDirectory() || Utils.dirExistsSync(srcPathResolved);\n\n    if (!isDirectory) {\n      return '';\n    }\n\n    if (moduleParentFolder.startsWith(srcPathResolved)) {\n      return moduleParentFolder.substring(srcPathResolved.length + 1).split(path.sep).join(Context.REPORT_KEY_SEPARATOR);\n    }\n\n    return '';\n  }\n\n  /**\n   * In case there are multiple sources, compute the moduleKey uniquely\n   *\n   * @param {Array} modulePathsCopy\n   * @param {Array} [modulePathParts]\n   * @param {string} [moduleKey]\n   * @return {string}\n   */\n  getUniqueModuleKey(modulePathsCopy, modulePathParts = null, moduleKey = '') {\n    if (modulePathParts && modulePathParts.length < 2) {\n      return moduleKey;\n    }\n\n    const isKeyUnique = !modulePathsCopy.some(item => {\n      const modulePath = path.sep + moduleKey;\n\n      return item.endsWith(modulePath + Utils.jsFileExt) || item.endsWith(modulePath + Utils.tsFileExt);\n    });\n\n    if (isKeyUnique) {\n      return moduleKey;\n    }\n\n    moduleKey = [modulePathParts.pop(), moduleKey].join(Context.REPORT_KEY_SEPARATOR);\n\n    return this.getUniqueModuleKey(modulePathsCopy, modulePathParts, moduleKey);\n  }\n}\n\nmodule.exports = Context;\n"
  },
  {
    "path": "lib/testsuite/globals.js",
    "content": "const path = require('path');\nconst lodashCloneDeep = require('lodash/cloneDeep');\nconst TestHooks = require('./hooks.js');\nconst Context = require('./context.js');\nconst Utils = require('../utils');\nconst {Logger} = Utils;\nconst PluginLoader = require('../api/_loaders/plugin.js');\n\nclass GlobalsContext extends Context {\n  throwError(err) {\n    err.detailedErr = err.message;\n    err.message = `cannot read external global file using \"${this.settings.globals_path}\"`;\n    err.showTrace = false;\n\n    throw err;\n  }\n\n  get isTestHook() {\n    return true;\n  }\n\n  constructor(settings, argv, currentEnv) {\n    super({modulePath: settings.globals_path, settings, argv});\n\n    this.currentEnv = currentEnv;\n    this.argv = argv;\n  }\n\n  get testsuite() {\n    return this.module;\n  }\n\n  init(asyncLoading) {\n    return this.initModule(() => {\n      if (asyncLoading) {\n        return this.loadModule();\n      }\n\n      return this.loadModuleSync();\n    }, () => {\n      this.externalGlobals = Object.assign({}, this.__module);\n      this.__module = this.settings.globals;\n\n      this.mergeGlobalsOntoSettings();\n      this.setCurrentEnv();\n    }, asyncLoading);\n  }\n\n  initModule(loadFn, callback, asyncLoading) {\n    if (!this.settings.globals_path) {\n      this.__module = this.settings.globals;\n      this.setCurrentEnv();\n\n      if (asyncLoading) {\n        return Promise.resolve();\n      }\n\n      return;\n    }\n\n    const result = loadFn.call(this);\n    if (result instanceof Promise) {\n      return result.then(() => {\n        callback.call(this);\n      });\n    }\n\n    callback.call(this);\n  }\n\n  async loadModule(isRetry = false) {\n    try {\n      this.__module = await Utils.requireModule(this.modulePath);\n\n      if (!this.__module) {\n        throw new Error(`Empty module provided in: \"${this.modulePath}\".`);\n      }\n    } catch (err) {\n      if (err.code === 'MODULE_NOT_FOUND' && !isRetry) {\n        this.modulePath = path.join(Utils.getConfigFolder(this.argv), this.settings.globals_path);\n        await this.loadModule(true);\n\n        return this;\n      }\n\n      this.throwError(err);\n    }\n  }\n\n  loadModuleSync(isRetry = false) {\n    try {\n      this.__module = Utils.requireModule(this.modulePath);\n\n      if (!this.__module) {\n        throw new Error(`Empty module provided in: \"${this.modulePath}\".`);\n      }\n    } catch (err) {\n      if (err.code === 'MODULE_NOT_FOUND' && !isRetry) {\n        this.modulePath = path.join(Utils.getConfigFolder(this.argv), this.settings.globals_path);\n        this.loadModuleSync(true);\n\n        return this;\n      }\n\n      this.throwError(err);\n    }\n\n    return this;\n  }\n\n  /**\n   * Merges the contents of the external globals back to the settings object in order for it to be available between\n   *  test runs;\n   *\n   * This can be either as it is, so that any changes on the globals are maintained, or as a deep copy\n   *\n   * @return {GlobalsContext}\n   */\n  mergeGlobalsOntoSettings() {\n    let externalGlobals;\n\n    if (this.settings.persist_globals) {\n      externalGlobals = this.externalGlobals;\n    } else {\n      // if we already have globals, make a copy of them\n      externalGlobals = lodashCloneDeep(this.externalGlobals);\n    }\n\n    Object.assign(this.__module, externalGlobals);\n\n    return this;\n  }\n\n  extendContextWithApi(context, api) {\n    if (('client' in context) && this.modulePath &&\n      context.client && !('currentTest' in context.client)) {\n      throw new Error('There is already a .client property defined in: ' + this.modulePath);\n    }\n\n    Object.defineProperty(context, 'client', {\n      enumerable: false,\n      configurable: false,\n      writable: true,\n      value: api\n    });\n  }\n\n  callAsync({fnName, api, expectedArgs = 2, isTestHook = false, isES6Async, done = function() {}}) {\n\n    if (isES6Async && isTestHook && expectedArgs === 1) {\n      return this.module[fnName].call(this.module, api)\n        .then(function(result) {\n          return done(result);\n        })\n        .catch(function(err) {\n          Logger.error(err);\n\n          return done(err);\n        });\n    }\n\n\n    const fnAsync = Utils.makeFnAsync(expectedArgs, this.module[fnName], this.module);\n    const args = this.getHookFnArgs(done, api, expectedArgs);\n\n    return fnAsync.apply(this.module, args);\n  }\n\n  /**\n   *\n   * @param {string} fnName\n   * @param args\n   */\n  call(fnName, ...args) {\n    const client = args[0];\n    if (client) {\n      client.isES6AsyncTestcase = this.isES6Async(fnName);\n      args[0] = client.api;\n    }\n\n    return this.module[fnName].apply(this.module, args);\n  }\n\n  hasHook(key) {\n    return typeof this.moduleCopy[key] == 'function';\n  }\n\n  getKey(key) {\n    return this.moduleCopy[key];\n  }\n\n  /**\n   *\n   * @param {function} done\n   * @param {Object} api\n   * @param {Number} expectedArgs\n   * @return []\n   */\n  getHookFnArgs(done, api, expectedArgs) {\n    return expectedArgs === 1 ? [done] : [api, done];\n  }\n\n  setCurrentEnv() {\n    this.moduleCopy = lodashCloneDeep(this.module);\n\n    // select globals from the current environment\n    if (this.currentEnv) {\n      /*eslint no-prototype-builtins: 'warn'*/\n      if (this.currentEnv && this.__module.hasOwnProperty(this.currentEnv)) {\n        Object.assign(this.__module, this.module[this.currentEnv]);\n      }\n    }\n  }\n}\n\nclass Globals {\n  constructor(settings, argv, currentEnv = '') {\n    this.settings = settings;\n    this.argv = argv;\n    this.currentEnv = currentEnv;\n  }\n\n  get globals() {\n    return this.context.module;\n  }\n\n  loadPlugins() {\n    const definition = this.settings.plugins || [];\n    this.plugins = definition.reduce((prev, pluginName) => {\n      const plugin = PluginLoader.load(pluginName);\n      if (plugin.globals) {\n        prev.push(plugin);\n      }\n\n      return prev;\n    }, []);\n  }\n\n  init() {\n    this.mergeWithExisting();\n    this.setupGlobalHooks();\n    this.loadPlugins();\n  }\n\n  readExternal(asyncLoading) {\n    this.context = new GlobalsContext(this.settings, this.argv, this.currentEnv);\n\n    return this.context.init(asyncLoading);\n  }\n\n  /**\n   * Shallow merge with existing globals on the settings object\n   */\n  mergeWithExisting() {\n    const settingsCopy = lodashCloneDeep(this.settings);\n    delete settingsCopy.globals;\n\n    try {\n      Object.defineProperty(this.globals, 'settings', {\n        enumerable: false,\n        configurable: false,\n        get() {\n          return settingsCopy;\n        }\n      });\n      // eslint-disable-next-line\n    } catch (err) {}\n\n    this.settings.globals = this.globals;\n  }\n\n  setupGlobalHooks() {\n    this.hooks = new TestHooks(this.context, {\n      isGlobal: true,\n      asyncHookTimeout: this.settings.globals.asyncHookTimeout\n    });\n  }\n\n  async runPluginHook(hookName, args) {\n    if (this.plugins.length === 0) {\n      return;\n    }\n\n    await Promise.all(this.plugins.map(plugin => {\n      if (Utils.isFunction(plugin.globals[hookName])) {\n        return plugin.globals[hookName].apply(this.settings.globals, args);\n      }\n\n      return Promise.resolve();\n    }));\n  }\n\n  async runGlobalHook(key, args = []) {\n    await this.hooks[key].run();\n    await this.runPluginHook(key, args);\n  }\n}\n\nmodule.exports = Globals;\n"
  },
  {
    "path": "lib/testsuite/hooks/_basehook.js",
    "content": "const Utils = require('../../utils');\nconst {TimedCallback} = Utils;\n\nclass BaseHook {\n  static get beforeAll() {\n    return 'before';\n  }\n\n  static get beforeEach() {\n    return 'beforeEach';\n  }\n\n  static get beforeChildProcess() {\n    return 'beforeChildProcess';\n  }\n\n  static get afterAll() {\n    return 'after';\n  }\n\n  static get afterEach() {\n    return 'afterEach';\n  }\n\n  static get afterChildProcess() {\n    return 'afterChildProcess';\n  }\n\n  get skipTestcasesOnError() {\n    return false;\n  }\n\n  constructor(hookName, context, addtOpts = {}) {\n    this.context = context;\n    this.addtOpts = addtOpts;\n    this.key = hookName;\n    this.hookTimeoutId = null;\n  }\n\n  get isGlobal() {\n    return this.addtOpts.isGlobal || false;\n  }\n\n  get isUnitTest() {\n    return false;\n  }\n\n  /**\n   *\n   * @param {Object} client The nightwatch main instance\n   * @param {function} [originalFn]\n   * @return {*}\n   */\n  run(client = null, originalFn = null) {\n    originalFn = originalFn || this.verifyMethod();\n\n    if (originalFn) {\n      const argsCount = originalFn.length;\n      let expectedCount;\n      let runnableDone;\n\n      return new Promise((resolve, reject) => {\n        try {\n          const timedCallback = this.createCallbackWrapper(resolve, reject, err => {\n            err.help = ['You can increase the hooks timeout by setting \"asyncHookTimeout\" in the globals config to the required value.'];\n            err.skipTestCases = this.skipTestcasesOnError;\n            runnableDone && runnableDone(err);\n            reject(err);\n          });\n\n          const doneFn = timedCallback.getWrapper();\n          if (!this.isGlobal) {\n            expectedCount = 2;\n          }\n\n          if (this.context.currentRunnable && argsCount === 2) {\n            // Set the runnable resolve function to be called from the inside the done callback of the hook\n            //  - necessary for the case when the callback starts a different async operation\n            runnableDone = this.context.currentRunnable.setDoneCallback();\n            this.context.currentRunnable.deffered.promise.catch(err => {\n              if (this.hookTimeoutId) {\n                clearTimeout(this.hookTimeoutId);\n              }\n              runnableDone(err);\n            });\n          }\n\n          const invocationResult = this.context.invokeMethod(this.key, client, argsCount, result => {\n            if (result instanceof Error) {\n              result.skipTestCases = this.skipTestcasesOnError;\n            }\n\n            if (this.context.queue && this.context.queue.inProgress) {\n              this.context.queue.once('queue:finished', _ => {\n                runnableDone && runnableDone(result);\n                doneFn(result);\n              });\n            } else {\n              runnableDone && runnableDone(result);\n              doneFn(result);\n            }\n          });\n\n          if (argsCount <= 1 && (invocationResult instanceof Promise)) {\n            invocationResult.catch(err => {\n              return err;\n            }).then(result => {\n              if (result instanceof Error) {\n                result.skipTestCases = this.skipTestcasesOnError;\n              }\n              runnableDone && runnableDone(result);\n              doneFn(result);\n\n              return result;\n            });\n          } else if (this.onlyApiArgPassed(argsCount)) {\n            // For global hooks (and unit tests), when we have only one argument, the argument is the \"done\" callback:\n            //  E.g.: (global) afterEach(done) {}\n            //\n            // For normal test hooks, the 1st argument is the 'client' object and the \"done\" callback is optional,\n            //  and thus the callback is called implicitly if it's not passed explicitly, e.g.: after(client) {}\n            this.implicitlyCallDoneCallback(doneFn);\n          }\n        } catch (err) {\n          if (this.hookTimeoutId) {\n            clearTimeout(this.hookTimeoutId);\n          }\n\n          runnableDone && runnableDone(err);\n\n          reject(err);\n        }\n      });\n    }\n\n    return Promise.resolve();\n  }\n\n  verifyMethod() {\n    if (this.context.hasHook(this.key)) {\n      return this.context.getKey(this.key);\n    }\n\n    return null;\n  }\n\n  /**\n   *\n   * @param {Function} resolve\n   * @param {Function} reject\n   * @param {Function} timeoutExpired\n   * @return {TimedCallback}\n   */\n  createCallbackWrapper(resolve, reject, timeoutExpired) {\n    const timedCallback = new TimedCallback(function doneCallback(err) {\n      if (Utils.isErrorObject(err)) {\n        return reject(err);\n      }\n\n      resolve();\n    }, ((this.isGlobal && !this.isUnitTest) ? 'global ' : '') + this.key, this.addtOpts.asyncHookTimeout);\n\n    timedCallback.onTimeoutExpired = timeoutExpired;\n\n    timedCallback.onTimerStarted = timeoutId => {\n      this.hookTimeoutId = timeoutId;\n    };\n\n    return timedCallback;\n  }\n\n  onlyApiArgPassed(argsCount) {\n    return argsCount === 1 && !this.isGlobal;\n  }\n\n  startQueueIfNeeded() {\n    if (!this.context.queueStarted) {\n      this.context.queue.run();\n    }\n  }\n\n  implicitlyCallDoneCallback(doneFn) {\n    if (this.hookTimeoutId) {\n      clearTimeout(this.hookTimeoutId);\n    }\n\n    process.nextTick(() => {\n      if (this.context.queue) {\n        this.context.queue.once('queue:finished', _ => {\n          doneFn();\n        });\n\n        this.startQueueIfNeeded();\n      }\n    });\n  }\n}\n\nmodule.exports = BaseHook;\n"
  },
  {
    "path": "lib/testsuite/hooks/afterAll.js",
    "content": "const BaseHook = require('./_basehook.js');\n\nclass AfterAll extends BaseHook {\n  constructor(context, addtOpts) {\n    super(BaseHook.afterAll, context, addtOpts);\n  }\n}\n\nmodule.exports = AfterAll;\n"
  },
  {
    "path": "lib/testsuite/hooks/afterChildProcess.js",
    "content": "const BaseHook = require('./_basehook.js');\n\nclass AfterChildProcess extends BaseHook {\n  constructor(context, addtOpts) {\n    super(BaseHook.afterChildProcess, context, addtOpts);\n  }\n}\n\nmodule.exports = AfterChildProcess;\n"
  },
  {
    "path": "lib/testsuite/hooks/afterEach.js",
    "content": "const BaseHook = require('./_basehook.js');\n\nclass AfterEach extends BaseHook {\n  constructor(context, addtOpts) {\n    super(BaseHook.afterEach, context, addtOpts);\n  }\n}\n\nmodule.exports = AfterEach;\n"
  },
  {
    "path": "lib/testsuite/hooks/beforeAll.js",
    "content": "const BaseHook = require('./_basehook.js');\n\nclass BeforeAll extends BaseHook {\n  get skipTestcasesOnError() {\n    return true;\n  }\n\n  constructor(context, addtOpts) {\n    super(BaseHook.beforeAll, context, addtOpts);\n  }\n}\n\nmodule.exports = BeforeAll;\n"
  },
  {
    "path": "lib/testsuite/hooks/beforeChildProcess.js",
    "content": "const BaseHook = require('./_basehook.js');\n\nclass BeforeChildProcess extends BaseHook {\n  constructor(context, addtOpts) {\n    super(BaseHook.beforeChildProcess, context, addtOpts);\n  }\n}\n\nmodule.exports = BeforeChildProcess;\n"
  },
  {
    "path": "lib/testsuite/hooks/beforeEach.js",
    "content": "const BaseHook = require('./_basehook.js');\n\nclass BeforeAll extends BaseHook {\n  get skipTestcasesOnError() {\n    return true;\n  }\n\n  constructor(context, addtOpts) {\n    super(BaseHook.beforeEach, context, addtOpts);\n  }\n}\n\nmodule.exports = BeforeAll;\n"
  },
  {
    "path": "lib/testsuite/hooks.js",
    "content": "const BaseHook = require('./hooks/_basehook.js');\n\nclass TestHooks {\n  static get TEST_HOOKS () {\n    return {\n      [BaseHook.beforeAll]: require('./hooks/beforeAll.js'),\n      [BaseHook.beforeEach]: require('./hooks/beforeEach.js'),\n      [BaseHook.beforeChildProcess]: require('./hooks/beforeChildProcess.js'),\n      [BaseHook.afterEach]: require('./hooks/afterEach.js'),\n      [BaseHook.afterAll]: require('./hooks/afterAll.js'),\n      [BaseHook.afterChildProcess]: require('./hooks/afterChildProcess.js')\n    };\n  }\n\n  constructor(context, addtOpts) {\n    this.context = context;\n\n    Object.keys(TestHooks.TEST_HOOKS).forEach(key => {\n      this[key] = new TestHooks.TEST_HOOKS[key](this.context, addtOpts);\n    });\n  }\n}\n\nmodule.exports = TestHooks;\n"
  },
  {
    "path": "lib/testsuite/index.js",
    "content": "const AssertionError = require('assertion-error');\nconst {By, Key, locateWith, withTagName} = require('selenium-webdriver');\n\n\nconst Reporter = require('../reporter');\nconst Context = require('./context.js');\nconst TestHooks = require('./hooks.js');\nconst TestCase = require('./testcase.js');\nconst Runnable = require('./runnable.js');\nconst Transport = require('../transport/selenium-webdriver');\nconst NightwatchAssertError = require('../assertion').AssertionError;\nconst SuiteRetries = require('./retries.js');\nconst NightwatchClient = require('../core/client.js');\nconst Concurrency = require('../runner/concurrency');\nconst ElementGlobal = require('../api/_loaders/element-global.js');\nconst {Logger, Screenshots, Snapshots, alwaysDisplayError, isString, isFunction, SafeJSON} = require('../utils');\nconst NightwatchInspectorServer = require('./nightwatch-inspector');\nconst {DEFAULT_RUNNER_EVENTS, NightwatchEventHub} = require('../runner/eventHub');\nconst {GlobalHook, TestSuiteHook} = DEFAULT_RUNNER_EVENTS;\n\n\nclass TestSuite {\n  constructor({modulePath, modules, settings, argv, usingMocha = false, addtOpts = {}}) {\n    this.settings = settings;\n    this.argv = argv;\n    this.modulePath = modulePath;\n    this.allModulePaths = modules;\n    this.testcase = null;\n    this.currentRunnable = null;\n    this.usingMocha = usingMocha;\n    this.reuseBrowser = argv['reuse-browser'] || (settings.globals && settings.globals.reuseBrowserSession);\n    this.globalHooks = addtOpts.globalHooks || {};\n    if (addtOpts.globalsInstance) {\n      this.globalsInstance = addtOpts.globalsInstance;\n    }\n    this.__reportPrefix = '';\n\n    this.mochaContext = new Promise(resolve => {\n      this.mochaContextResolve = resolve;\n    });\n  }\n\n  get api() {\n    return this.client.api;\n  }\n\n  get commandQueue() {\n    if (!this.client) {\n      return null;\n    }\n\n    return this.client.queue;\n  }\n\n  get reportPrefix() {\n    return this.__reportPrefix;\n  }\n\n  get transport() {\n    return this.client.transport;\n  }\n\n  get skipTestcasesOnFail() {\n    const localDefinedValue = this.context.getSkipTestcasesOnFail();\n\n    if (localDefinedValue !== undefined) {\n      return localDefinedValue;\n    }\n\n    const settingsValueUndefined = this.settings.skip_testcases_on_fail === undefined;\n    if (settingsValueUndefined && this.context.unitTestingMode) {\n      // false by default when running unit tests\n      return false;\n    }\n\n    // true by default when not running unit tests\n    return settingsValueUndefined || this.settings.skip_testcases_on_fail;\n  }\n\n  get endSessionOnFail() {\n    const definedValue = this.context.getEndSessionOnFail();\n\n    return definedValue === undefined ? this.settings.end_session_on_fail : definedValue;\n  }\n\n  get isES6Async() {\n    return this.client && (this.client.isES6AsyncTestcase || this.client.isES6AsyncTestHook);\n  }\n\n  get failFastMode() {\n    return this.argv['fail-fast'] || this.settings.enable_fail_fast;\n  }\n\n  isComponentTestingMode() {\n    return this.api.globals.component_tests_mode;\n  }\n\n  isE2EPreviewMode() {\n    return this.argv['launch-url'];\n  }\n\n  shouldSkipTestsOnFail() {\n    return this.skipTestcasesOnFail && !this.context.unitTestingMode || this.failFastMode;\n  }\n\n  async initCommon(opts = {}) {\n    if (!this.settings.unit_testing_mode) {\n      this.addPropertiesToGlobalScope();\n    }\n\n    await this.initClient(opts);\n\n    if (this.isE2EPreviewMode()) {\n      this.context = {\n        getDesiredCapabilities() {},\n        isDisabled() {\n          return false;\n        }\n      };\n      this.reporter = {\n        registerTestError(err) {\n          Logger.error(err);\n        }\n      };\n    } else {\n      await this.createContext(opts);\n    }\n\n    this.mochaContextResolve(this.context);\n\n    this.setSuiteName();\n    this.setRetries();\n  }\n\n  async init(opts = {}) {\n    await this.initCommon(opts);\n    this.updateClient();\n    this.setupHooks();\n\n    return this;\n  }\n\n  setModulePath(file) {\n    this.modulePath = file;\n    this.context.modulePath = file;\n  }\n\n  validateNightwatchInspectorCriteria() {\n    return (\n      this.argv.debug &&\n      Concurrency.isMasterProcess() &&\n      this.client.api.isChrome()\n    );\n  }\n\n  async initClient({initialize = true} = {}) {\n    const settings = Object.assign({}, this.settings);\n\n    this.client = NightwatchClient.create(settings, this.argv);\n    if (initialize) {\n      await this.client.initialize();\n    }\n\n    if (this.validateNightwatchInspectorCriteria()) {\n      this.globalsInstance.inspectorServer?.closeSocket();\n      this.globalsInstance.inspectorServer = new NightwatchInspectorServer(this.client);\n    }\n  }\n\n  updateClient() {\n    // this is necessary because mocha as a different suite setup flow\n    if (!this.settings.disable_global_apis) {\n      Object.defineProperty(global, 'browser', {\n        configurable: true,\n        get: function() {\n          return this.client.api;\n        }.bind(this)\n      });\n    }\n\n    if (this.settings.sync_test_names) {\n      this.client.mergeCapabilities({\n        name: this.suiteName\n      });\n    }\n\n    if (this.context.getDesiredCapabilities()) {\n      this.client.mergeCapabilities(this.context.getDesiredCapabilities());\n    }\n\n    this.client.createTransport();\n\n    if (!this.isE2EPreviewMode()) {\n      this.createReporter();\n\n      this.client\n        .setReporter(this.reporter)\n        .setCurrentTest();\n    }\n\n    return this;\n  }\n\n  async retrySuite() {\n    this.suiteRetries.incrementSuiteRetriesCount();\n\n    await this.terminate('RETRY_SUITE');\n\n    await this.createContext({reloadModuleCache: this.context.usingBddDescribe});\n    await this.createClient();\n    this.setupHooks();\n\n    return this.run();\n  }\n\n  createReporter() {\n    if (!this.context) {\n      throw new Error('Context must be created before creating the reporter.');\n    }\n\n    const {suiteRetries, suiteName} = this;\n    const {tests, moduleKey, modulePath, groupName, skippedTests, allScreenedTests} = this.context;\n\n    this.reporter = new Reporter({\n      settings: this.client.settings,\n      tests,\n      suiteRetries,\n      addOpts: {\n        reporter: this.argv.reporter,\n        suiteName,\n        moduleKey,\n        modulePath,\n        reportPrefix: '',\n        reportFileName: this.argv['report-filename'],\n        groupName,\n        isMobile: this.client.api.isMobile(),\n        tags: this.context.getTags()\n      },\n      skippedTests,\n      allScreenedTests\n    });\n  }\n\n  async createClient(client = null) {\n    if (client) {\n      this.client = client;\n\n      return this;\n    }\n\n    await this.initClient();\n    this.updateClient();\n\n    return this;\n  }\n\n  async createContext({context = null, reloadModuleCache = false, suiteTitle = null, attributes = {}} = {}) {\n    if (context) {\n      this.context = context;\n\n      return this;\n    }\n\n    const {modulePath, settings, argv, client} = this;\n    this.context = new Context({modulePath, settings, argv, attributes});\n\n    if (settings.tag_filter && settings.tag_filter.length > 0) {\n      reloadModuleCache = true;\n    }\n\n    this.context.setReloadModuleCache(reloadModuleCache);\n\n    await this.context.init({usingMocha: this.usingMocha, suiteTitle, client});\n\n    this.context.setReportKey(this.allModulePaths);\n\n    return this;\n  }\n\n  addPropertiesToGlobalScope() {\n    if (this.settings.disable_global_apis) {\n      return null;\n    }\n\n    Object.defineProperty(global, 'app', {\n      configurable: true,\n      get: function() {\n        return global.browser;\n      }\n    });\n\n    Object.defineProperty(global, 'by', {\n      configurable: true,\n      get: function() {\n        return By;\n      }\n    });\n\n    Object.defineProperty(global, 'By', {\n      configurable: true,\n      get: function() {\n        return By;\n      }\n    });\n\n    Object.defineProperty(global, 'locateWith', {\n      configurable: true,\n      get: function() {\n        return locateWith;\n      }\n    });\n\n    Object.defineProperty(global, 'withTagName', {\n      configurable: true,\n      get: function() {\n        return withTagName;\n      }\n    });\n\n    Object.defineProperty(global, 'Keys', {\n      configurable: true,\n      get: function() {\n        return Key;\n      }\n    });\n\n    Object.defineProperty(global, 'element', {\n      configurable: true,\n      value: function(locator, options = {}) {\n        return ElementGlobal.element({locator, testSuite: this, options, client: this.client});\n      }.bind(this),\n      writable: false\n    });\n\n    if (this.settings.disable_global_expect) {\n      return null;\n    }\n\n    const globalExpect = function(...args) {\n      return global.browser.expect(...args);\n    };\n\n    Object.defineProperty(globalExpect, 'element', {\n      value: function(...args) {\n        return global.browser.expect.element(...args);\n      },\n      writable: false\n    });\n\n    Object.defineProperty(globalExpect, 'elements', {\n      value: function(...args) {\n        return global.browser.expect.elements(...args);\n      },\n      writable: false\n    });\n\n    Object.defineProperty(globalExpect, 'component', {\n      value: function(...args) {\n        return global.browser.expect.component(...args);\n      },\n      writable: false\n    });\n\n    Object.defineProperty(globalExpect, 'title', {\n      value: function(...args) {\n        return global.browser.expect.title(...args);\n      },\n      writable: false\n    });\n\n    Object.defineProperty(globalExpect, 'cookie', {\n      value: function(...args) {\n        return global.browser.expect.cookie(...args);\n      },\n      writable: false\n    });\n\n    Object.defineProperty(globalExpect, 'url', {\n      value: function(...args) {\n        return global.browser.expect.url(...args);\n      },\n      writable: false\n    });\n    Object.freeze(globalExpect);\n\n    Object.defineProperty(global, 'expect', {\n      configurable: true,\n      get: function() {\n        return globalExpect;\n      }\n    });\n  }\n\n  setUncaughtError(err) {\n    this.uncaughtError = err;\n  }\n\n  setReportPrefix(data) {\n    this.settings.report_prefix = this.__reportPrefix = '';\n\n    if (!data) {\n      return this;\n    }\n\n    const capabilities = data.capabilities || {};\n    const browserName = (capabilities.browserName && capabilities.browserName.toUpperCase()) || '';\n    const browserVersion = capabilities.version || capabilities.browserVersion || '';\n    const platformVersion = capabilities.platform || capabilities.platformVersion || '';\n\n    if (!this.context.unitTestingMode) {\n      this.settings.report_prefix = this.__reportPrefix = `${browserName}_${browserVersion}_${platformVersion}_`.replace(/ /g, '_');\n    }\n\n    this.reporter.setFileNamePrefix(this.reportPrefix);\n\n    return this;\n  }\n\n  setRetries() {\n    if (this.isE2EPreviewMode()) {\n      return this;\n    }\n\n    this.suiteRetries = new SuiteRetries({\n      retries: this.context.retries.testcase || this.argv.retries,\n      suiteRetries: this.context.retries.suite || this.argv.suiteRetries\n    });\n\n    return this;\n  }\n\n  setSuiteName() {\n    if (this.isE2EPreviewMode()) {\n      this.suiteName = 'Preview';\n    } else {\n      this.suiteName = this.context.getSuiteName();\n    }\n\n    return this;\n  }\n\n  /**\n   * Instantiates the test hooks\n   *\n   * @return {TestSuite}\n   */\n  setupHooks() {\n    this.hooks = new TestHooks(this.context, {\n      asyncHookTimeout: this.settings.globals.asyncHookTimeout\n    });\n\n    return this;\n  }\n\n  runHook(hookName) {\n    Logger.log(`${Logger.colors.green('→')} Running [${hookName}]:`);\n\n    if (this.context.hasHook(hookName)) {\n      NightwatchEventHub.emit(TestSuiteHook[hookName].started, this.reporter.testResults.eventDataToEmit);\n    }\n\n    if (hookName === 'beforeEach' || hookName === 'afterEach') {\n      this.client.reporter.markHookRun(hookName);\n    }\n\n    if (hookName === 'before' || hookName === 'after') {\n      this.client.reporter.setCurrentSection({testName: `__${hookName}_hook`});\n    }\n\n    return this.handleRunnable(hookName, () => {\n      return this.hooks[hookName].run(this.client);\n    }).then(result => {\n      if (this.context.hasHook(hookName)) {\n        NightwatchEventHub.emit(TestSuiteHook[hookName].finished, this.reporter.testResults.eventDataToEmit);\n      }\n\n      if (hookName === 'beforeEach' || hookName === 'afterEach') {\n        this.client.reporter.unmarkHookRun(hookName);\n      }\n\n      Logger.log(`${Logger.colors.green('→')} Completed [${hookName}].`);\n\n      return result;\n    });\n  }\n\n  runGlobalHook(hookName) {\n    const {globals} = this.settings;\n\n    if (globals[hookName]) {\n      NightwatchEventHub.emit(GlobalHook[hookName].started, this.reporter.testResults.eventDataToEmit);\n    }\n\n    if (!this.globalHooks[hookName]) {\n      return Promise.resolve();\n    }\n\n    this.client.reporter.setCurrentSection({testName: `__global_${hookName}_hook`});\n\n    return this.handleRunnable(hookName, async () => {\n      if (this.globalsInstance) {\n        await this.globalsInstance.runPluginHook(hookName, [this.settings]);\n      }\n\n      const result = await this.globalHooks[hookName].run(this.client);\n\n      if (globals[hookName]) {\n        NightwatchEventHub.emit(GlobalHook[hookName].finished, this.reporter.testResults.eventDataToEmit);\n      }\n\n      this.onTestSectionFinished();\n\n      return result;\n    });\n  }\n\n  createSession() {\n    if (this.client.sessionId || this.context.unitTestingMode) {\n      return Promise.resolve();\n    }\n\n    const {argv, reuseBrowser} = this;\n    const {moduleKey} = this.context;\n\n    return this.client.createSession({argv, moduleKey, reuseBrowser}).catch(err => {\n      err.sessionCreate = true;\n\n      this.reporter.registerTestError(err);\n\n      throw err;\n    });\n  }\n\n  async startTestSuite() {\n    NightwatchEventHub.emit(TestSuiteHook.started, this.reporter.testResults.eventDataToEmit);\n\n    if (!this.client) {\n      await this.createClient();\n      this.setupHooks();\n    }\n\n    return this.createSession()\n      .then(data => {\n        this.setReportPrefix(data);\n        // Adding session info to report\n        if (data) {\n          this.reporter.setSessionInfo(data);\n\n          if (data.capabilities && data.capabilities['safari:deviceUDID']) {\n            this.settings.deviceUDID = data.capabilities['safari:deviceUDID'];\n          }\n        }\n\n        this.commandQueue.tree.on('asynctree:command:finished', this.onCommandFinished.bind(this));\n\n        return this.runGlobalHook('beforeEach');\n      });\n  }\n\n  /**\n   * Runs the test suite, including all hooks\n   */\n  runTestSuite() {\n    if (this.isE2EPreviewMode()) {\n      return this.createSession()\n        .then(_ => {\n          const runnable = new Runnable('preview', _ => {\n            const url = isString(this.argv.preview) ? this.argv.preview : this.api.launchUrl;\n            this.api.url(url).pause();\n          });\n\n          return runnable.run(this.commandQueue);\n        })\n        .then(_ => this.stopSession());\n    }\n\n    return this.startTestSuite()\n      .then(() => this.runHook('before'))\n      .then(result => {\n        this.onTestSectionFinished();\n\n        if (result instanceof Error) {\n          Logger.error(result);\n        }\n\n        return this.runNextTestCase();\n      })\n      .catch(err => {\n        if (err.sessionCreate) {\n          throw err;\n        }\n\n        if (!this.isAssertionError(err) && !this.context.unitTestingMode && !this.failFastMode) {\n          if (!this.shouldSkipTestsOnFail()){\n            Logger.error(err);\n          }\n          err.displayed = true;\n        }\n\n        // testcase failed - this catch ensures that the after hook is being called\n        return err;\n      })\n      .then(possibleError => {\n        this.reporter.resetCurrentTestName();\n\n        return this.runHook('after')\n          .catch(err => {\n            // exceptions from after hook\n            if (!possibleError) {\n              possibleError = err;\n            }\n\n            return err;\n          })\n          .then(result => {\n            if ((possibleError instanceof Error) && this.failFastMode) {\n              throw possibleError;\n            }\n            this.onTestSectionFinished();\n\n            return result;\n          });\n      })\n      .catch(err => {\n        // testsuite failed - this catch ensures that the global afterEach will always run\n        return this.terminate('FAILED', err);\n      })\n      .then((errorOrFailures) => this.onTestSuiteFinished(errorOrFailures));\n  }\n\n  onTestSectionFinished() {\n    // called for all test cases and hooks (except for [before|after]_each hooks)\n    // ^ [before|after]_each hooks are considered part of the test case itself\n    this.reporter.setTestStatus();\n    this.reporter.setTestSectionElapsedTime();\n    this.reporter.collectTestSectionOutput();\n  }\n\n  onTestSuiteFinished(errorOrFailures = false) {\n    this.__snapShot = undefined;\n\n    return this.runGlobalHook('afterEach')\n      .then(result => {\n        if (!(errorOrFailures instanceof Error)) {\n          return result;\n        }\n\n        if ((errorOrFailures.sessionCreate && this.failFastMode)) {\n          //throw errorOrFailures;\n        }\n\n        if (this.failFastMode && !this.shouldRetrySuite(errorOrFailures)) {\n          throw errorOrFailures;\n        }\n      })\n      .catch(err => {\n        if (err.sessionCreate || this.failFastMode) {\n          throw err;\n        }\n\n        if (!err.displayed) {\n          Logger.error(err);\n        }\n\n        // catching errors thrown inside the global afterEach\n        return err;\n      })\n      .then(failedResult => {\n        if (this.shouldRetrySuite(errorOrFailures)) {\n          return this.retrySuite();\n        }\n\n        const failures = errorOrFailures || failedResult || !this.reporter.allTestsPassed;\n\n        return this.stopSession(failures);\n      });\n  }\n\n  onCommandFinished({node, result}) {\n    this.reporter.logCommandResult({node, result});\n    this.takeSnapshot(node);\n  }\n\n  async stopSession(failures) {\n    try {\n      await this.terminate(failures ? 'FAILED' : '');\n    } catch (err) {\n      Logger.error(`Could not stop session in ${this.suiteName}:`);\n      Logger.error(err);\n    }\n\n    return this.testSuiteFinished(failures);\n  }\n\n  sendReportToParentWorker() {\n    if (this.settings.use_child_process && typeof process.send === 'function') {\n      process.send(SafeJSON.stringify({\n        type: 'testsuite_finished',\n        itemKey: process.env.__NIGHTWATCH_ENV_LABEL,\n        results: this.reporter.exportResults(),\n        httpOutput: Logger.collectOutput()\n      }));\n    } else if (process.port && typeof process.port.postMessage === 'function') {\n      process.port.postMessage(SafeJSON.stringify({\n        type: 'testsuite_finished',\n        results: this.reporter.exportResults(),\n        httpOutput: Logger.collectOutput()\n      }));\n    }\n  }\n\n  testSuiteFinished(failures) {\n    this.reporter.testSuiteFinished();\n    this.currentRunnable = null;\n\n    if (Concurrency.isWorker()) {\n      this.sendReportToParentWorker();\n    }\n\n    NightwatchEventHub.emit(TestSuiteHook.finished, this.reporter.testResults.eventDataToEmit);\n\n    return failures;\n  }\n\n  async sessionFinished(reason) {\n    let lastError = null;\n\n    if (reason === 'FAILED' || reason === 'RETRY_SUITE') {\n      lastError = this.reporter.testResults.lastError;\n    }\n\n    await this.transport.sessionFinished(reason, lastError);\n  }\n\n  async terminate(reason = 'SIGINT', potentialError = null, endSession = !this.reuseBrowser) {\n    this.resetQueue();\n\n    if (!this.client.sessionId || this.context.unitTestingMode) {\n      try {\n        await this.sessionFinished(reason);\n      } catch (err) {\n        return err;\n      }\n\n      return potentialError;\n    }\n\n    if (!this.endSessionOnFail && reason === 'FAILED') {\n\n      // Keep the session open; avoid reusing of same session\n      Transport.driver = null;\n      Transport.driverService = null;\n\n      return potentialError;\n    }\n\n\n    if (endSession) {\n      const runnable = new Runnable('terminate', _ => {\n        if (this.api && isFunction(this.api.end)) {\n          this.api.end(endSession);\n        }\n      }, {\n        isES6Async: this.isES6Async\n      });\n\n      return runnable\n        .run(this.commandQueue)\n        .then(async result => {\n          try {\n            await this.sessionFinished(reason);\n          } catch (err) {\n            return err;\n          }\n\n          return result;\n        })\n        .then(result => {\n          if ((potentialError instanceof Error) && (potentialError.sessionCreate || this.failFastMode)) {\n            return potentialError;\n          }\n\n          return result;\n        });\n    }\n  }\n\n  setReporterCurrentTest() {\n    // called for every test case (not for hooks)\n    this.reporter.setCurrentTest(this.testcase, this.context);\n    this.client.setCurrentTest();\n\n    return this;\n  }\n\n  /**\n   * Sets the next testcase and starts running it, if there is one\n   *\n   * @return {Promise}\n   */\n  runNextTestCase() {\n    const nextTestCase = this.context.getNextKey();\n\n    if (nextTestCase) {\n      return this.runCurrentTest(nextTestCase);\n    }\n\n    return Promise.resolve();\n  }\n\n  /**\n   * Runs the current testcase, including retries\n   *\n   * @param testName\n   * @return {Promise}\n   */\n  runCurrentTest(testName) {\n    const {reporter, context, settings} = this;\n\n    this.testcase = new TestCase(testName, {\n      context,\n      settings,\n      reporter,\n      addtOpts: {\n        retriesCount: this.suiteRetries.testRetriesCount[testName],\n        maxRetries: this.suiteRetries.testMaxRetries\n      }\n    });\n\n    this.setReporterCurrentTest().emptyQueue();\n\n    return this.createSession()\n      .then(() => this.runHook('beforeEach'))\n      .then(_ => {\n        this.client.reporter.markHookRun('testcase');\n\n        NightwatchEventHub.emit(TestSuiteHook.test.started, {\n          ...this.reporter.testResults.eventDataToEmit,\n          testcase: this.reporter.testResults.currentTestName,\n          settings: this.reporter.settings,\n          testCaseData: this.testcase\n        });\n\n        return this.handleRunnable(this.testcase.testName, () => this.testcase.run(this.client));\n      })\n      .catch(err => {\n        return err;\n      })\n      .then(possibleError => {\n        this.client.reporter.unmarkHookRun();\n\n        NightwatchEventHub.emit(TestSuiteHook.test.finished, {\n          ...this.reporter.testResults.eventDataToEmit,\n          testcase: this.reporter.testResults.currentTestName,\n          settings: this.reporter.settings,\n          testCaseData: this.testcase\n        });\n\n        if (this.transport.driverService && this.reporter.testResults) {\n          this.reporter.testResults.setSeleniumLogFile(this.transport.driverService.getSeleniumOutputFilePath());\n        }\n\n        // if there was an error in the testcase and skip_testcases_on_fail, we must send it forward, but after we run afterEach and after hooks\n        return this.runHook('afterEach')\n          .then(() => this.testCaseFinished())\n          .then(() => possibleError);\n      })\n      .then(possibleError => {\n        if (this.shouldRetryTestCase()) {\n          return this.retryCurrentTestCase();\n        }\n\n        if ((possibleError instanceof Error) && this.shouldSkipTestsOnFail()) {\n          throw possibleError;\n        }\n\n        return this.runNextTestCase();\n      });\n  }\n\n  testCaseFinished() {\n    this.reporter.setElapsedTime();\n    this.onTestSectionFinished();\n\n    if (!this.testcase) {\n      return Promise.resolve();\n    }\n\n    return this.reporter.printTestResult();\n  }\n\n  shouldRetryTestCase() {\n    return !this.reporter.currentTestCasePassed && this.suiteRetries.shouldRetryTest(this.testcase.testName);\n  }\n\n  retryCurrentTestCase() {\n    const currentTestName = this.testcase.testName;\n    this.suiteRetries.incrementTestRetriesCount(currentTestName);\n    this.reporter.resetCurrentTestPassedCount();\n    this.reporter.testResults.retryTest = true;\n    this.commandQueue.clearScheduled();\n\n    return this.runCurrentTest(currentTestName);\n  }\n\n  isScreenshotEnabled() {\n    return this.settings.screenshots.enabled;\n  }\n\n  shouldTakeScreenshotOnError() {\n    return this.isScreenshotEnabled() && this.settings.screenshots.on_error;\n  }\n\n  shouldTakeScreenshotOnFailure() {\n    return this.isScreenshotEnabled() && this.settings.screenshots.on_failure;\n  }\n\n  getScreenshotFilenamePath() {\n    return Screenshots.getFileName({\n      testSuite: this.api.currentTest.module,\n      testCase: this.api.currentTest.name\n    }, this.settings.screenshots);\n  }\n\n  takeScreenshot() {\n    const fileNamePath = this.getScreenshotFilenamePath();\n    const runnable = new Runnable('screenshot', _ => {\n      return new Promise((resolve) => {\n        this.api.saveScreenshot(fileNamePath, (result, err) => {\n          if (!err && this.transport.isResultSuccess(result))  {\n            const assertions = this.api.currentTest.results.assertions || [];\n            const commands = this.reporter.currentSection.commands || [];\n\n            if (assertions.length > 0) {\n              const currentAssertion = assertions[assertions.length - 1];\n              const currentCommand = commands[commands.length - 1];\n\n              if (currentAssertion) {\n                currentAssertion.screenshots = currentAssertion.screenshots || [];\n                currentAssertion.screenshots.push(fileNamePath);\n              }\n\n              if (currentCommand) {\n                currentCommand.screenshot = fileNamePath;\n              }\n            }\n          } else {\n            Logger.warn('Error saving screenshot...', err || result);\n          }\n          resolve();\n        });\n      });\n    });\n\n    return runnable.run(this.commandQueue);\n  }\n\n  takeSnapshot(node) {\n    const commands = this.reporter.currentSection.commands || [];\n    const currentCommand = commands[commands.length - 1];\n\n    if (this.settings.trace.enabled && node.isTraceable) {\n      const snapShotPath = Snapshots.getFileName({\n        testSuite: this.api.currentTest.module,\n        commandName: node.fullName,\n        traceSettings: this.settings.trace,\n        output_folder: this.settings.output_folder\n      });\n\n      this.__snapShot = new Promise((resolve, reject) => {\n        this.api.saveSnapshot(snapShotPath, (result => {\n          if (currentCommand) {\n            currentCommand.domSnapshot = result;\n          }\n          resolve(result);\n        }));\n      });\n    } else {\n      if (currentCommand && this.__snapShot) {\n        this.__snapShot.then(prevSnapshot => {\n          currentCommand.domSnapshot = prevSnapshot;\n        });\n      }\n    }\n  }\n\n  shouldRetrySuite(failures = false) {\n    if ((failures instanceof Error) && alwaysDisplayError(failures)) {\n      return false;\n    }\n\n    return (failures || !this.reporter.allTestsPassed) && this.suiteRetries.shouldRetrySuite();\n  }\n\n  async executeRunnable(name, fn) {\n    this.currentRunnable = new Runnable(name, fn, {\n      isES6Async: this.isES6Async\n    });\n\n    if (!this.context) {\n      return;\n    }\n\n    this.context.setCurrentRunnable(this.currentRunnable);\n\n    try {\n      const result = await this.currentRunnable.run(this.commandQueue);\n\n      return result;\n    } catch (err) {\n      return new Promise((resolve, reject) => {\n        setTimeout(() => {\n          reject(err);\n        }, 50);\n      });\n    }\n\n  }\n\n  async handleRunnable(name, fn) {\n    try {\n      const result = await this.executeRunnable(name, fn);\n\n      return result;\n    } catch (err) {\n      // if some other error was thrown, jump to the next catch\n      err.name = err.name || '';\n      if (!this.isAssertionError(err) && err.name !== 'TypeError') {\n        // registering non-assert errors\n        this.reporter.registerTestError(err);\n\n        if (this.shouldTakeScreenshotOnError()) {\n          await this.takeScreenshot();\n        }\n\n        throw err;\n      }\n\n      // if the assertion error was thrown by another assertion library\n      if (!(err instanceof NightwatchAssertError)) {\n        const failureMessage = `expected \"${err.expected}\" but got: \"${err.actual}\"`;\n        if (err.actual !== undefined && err.expected !== undefined) {\n          err.message += ` - ${failureMessage}`;\n        }\n\n        Logger.error(err);\n        this.reporter.registerFailed(err);\n        this.reporter.logAssertResult({\n          name: err.name,\n          message: err.message,\n          stackTrace: err.stack,\n          fullMsg: err.message,\n          failure: failureMessage\n        });\n      }\n\n      if (this.shouldTakeScreenshotOnFailure()) {\n        await this.takeScreenshot();\n      }\n      // clearing the queue here to avoid continuing with the rest of the testcase,\n      // unless abortOnFailure is set to false\n      if (!this.isAssertionError(err) || err.abortOnFailure) {\n        this.emptyQueue();\n      }\n\n      // set to true inside before/beforeEach hooks\n      if (err.skipTestCases) {\n        throw err;\n      }\n\n      return err;\n    }\n  }\n\n  print() {\n    if (this.isE2EPreviewMode()) {\n      Logger.info('Previewing...');\n\n      return this;\n    }\n\n    if (this.settings.output) {\n      let testSuiteDisplay;\n      const retriesCount = this.suiteRetries.suiteRetriesCount;\n\n      if (this.context.unitTestingMode) {\n        testSuiteDisplay = this.context.moduleName || this.context.moduleKey;\n      } else {\n        testSuiteDisplay = `[${this.suiteName}] Test Suite`;\n      }\n\n      if (this.settings.test_workers && !this.settings.live_output || this.context.unitTestingMode) {\n        // eslint-disable-next-line no-console\n        console.log('');\n      }\n\n      if (retriesCount > 0) {\n        // eslint-disable-next-line no-console\n        console.log('\\nRetrying: ', Logger.colors.red(testSuiteDisplay), `(${retriesCount}/${this.suiteRetries.suiteMaxRetries}): `);\n      } else if (this.context.unitTestingMode) {\n        // eslint-disable-next-line no-console\n        (this.context.isDisabled() ? Logger.info : console.log)(Logger.colors.cyan('[' + this.context.moduleKey + ']'));\n      } else {\n        Logger[this.context.isDisabled() ? 'info' : 'logDetailedMessage'](`\\n${Logger.colors.cyan(testSuiteDisplay)}`);\n      }\n\n      if (!this.context.unitTestingMode) {\n        Logger[this.context.isDisabled() ? 'info' : 'logDetailedMessage'](Logger.colors.purple(new Array(Math.min(testSuiteDisplay.length * 2 + 1, 80)).join('─')));\n      }\n    }\n\n    return this;\n  }\n\n  resetQueue() {\n    if (!this.commandQueue) {\n      return this;\n    }\n\n    this.commandQueue.reset().removeAllListeners();\n\n    return this;\n  }\n\n  emptyQueue() {\n    this.resetQueue();\n\n    if (this.commandQueue) {\n      this.commandQueue.empty();\n    }\n\n    return this;\n  }\n\n  /**\n   *\n   * @return {*}\n   */\n  run() {\n    this.print();\n\n    if (this.context.isDisabled()) {\n      // eslint-disable-next-line no-console\n      console.log(Logger.colors.green(`Testsuite \"${this.context.moduleName}\" is disabled, skipping...`));\n\n      // send report even if test is skipped\n      if (Concurrency.isWorker()) {\n        this.sendReportToParentWorker();\n      }\n\n      return Promise.resolve();\n    }\n\n    return this.runTestSuite();\n  }\n\n  isAssertionError(err) {\n    return (err instanceof AssertionError) || err.name.startsWith('AssertionError');\n  }\n}\n\n\n\nmodule.exports = TestSuite;\nmodule.exports.Context = Context;\n"
  },
  {
    "path": "lib/testsuite/interfaces/common.js",
    "content": "const TestHooks = require('../hooks.js');\n\nmodule.exports = class CommonInterface {\n  static get TestHooks() {\n    return Object.keys(TestHooks.TEST_HOOKS);\n  }\n\n  static get DEFAULT_ATTRIBUTES() {\n    return {\n      '@unitTest': false,\n      '@name': undefined,\n      '@endSessionOnFail': undefined,\n      '@skipTestcasesOnFail': undefined,\n      '@disabled': false,\n      '@desiredCapabilities': null,\n      '@tags': null\n    };\n  }\n\n  constructor(instance) {\n    this.instance = instance;\n    this.modulePath = instance.modulePath;\n    this.currentTest = instance.currentTest;\n  }\n\n  createInterface() {}\n};\n"
  },
  {
    "path": "lib/testsuite/interfaces/describe.js",
    "content": "const Utils = require('../../utils');\nconst Common = require('./common.js');\n\n/*\ndescribe('test suite', function() {\n\n  this.timeout(1000);\n});\n*/\n\nclass DescribeInstance {\n  constructor({describeTitle, instance, client}) {\n    this['[instance]'] = instance;\n    this['[attributes]'] = {};\n    this['[client]'] = client;\n    this.define('@name', describeTitle);\n  }\n\n  /////////////////////////////////////////////////\n  // Attributes\n  /////////////////////////////////////////////////\n  get name() {\n    return this['[attributes]']['@name'];\n  }\n\n  set tags(value) {\n    this.define('@tags', value);\n  }\n\n  get tags() {\n    return this['[attributes]']['@tags'];\n  }\n\n  set unitTest(value) {\n    this.define('@unitTest', value);\n  }\n\n  get unitTest() {\n    return this['[attributes]']['@unitTest'];\n  }\n\n  set endSessionOnFail(value) {\n    this.define('@endSessionOnFail', value);\n  }\n\n  get endSessionOnFail() {\n    return this['[attributes]']['@endSessionOnFail'];\n  }\n\n  set skipTestcasesOnFail(value) {\n    this.define('@skipTestcasesOnFail', value);\n  }\n\n  get skipTestcasesOnFail() {\n    return this['[attributes]']['@skipTestcasesOnFail'];\n  }\n\n  set disabled(value) {\n    this.define('@disabled', value);\n  }\n\n  get disabled() {\n    return this['[attributes]']['@disabled'];\n  }\n\n  set desiredCapabilities(value) {\n    if (Utils.isObject(value) || Utils.isFunction(value)) {\n      this.define('@desiredCapabilities', value);\n    }\n  }\n\n  get desiredCapabilities() {\n    return this['[client]'].initialCapabilities;\n  }\n  /////////////////////////////////////////////////\n  // Getters\n  /////////////////////////////////////////////////\n  get page() {\n    if (this['[client]'] && this['[client]'].api) {\n      return this['[client]'].api.page;\n    }\n\n    return null;\n  }\n\n  get globals() {\n    return this.settings.globals;\n  }\n\n  get settings() {\n    if (this['[client]']) {\n      return this['[client]'].settings;\n    }\n\n    return this['[instance]'].settings;\n  }\n\n  get argv() {\n    return this['[instance]'].argv;\n  }\n\n  timeout(value) {\n    this.globals.waitForConditionTimeout = value;\n    this.globals.retryAssertionTimeout = value;\n    this.globals.unitTestsTimeout = value;\n  }\n\n  waitForTimeout(value) {\n    if (typeof value == 'undefined') {\n      return this.globals.waitForConditionTimeout;\n    }\n\n    return this.timeout(value);\n  }\n\n  waitForRetryInterval(value) {\n    if (typeof value == 'undefined') {\n      return this.globals.waitForConditionPollInterval;\n    }\n\n    return this.retryInterval(value);\n  }\n\n  retryInterval(value) {\n    this.globals.waitForConditionPollInterval = value;\n  }\n\n  retries(n) {\n    this['[instance]'].setTestcaseRetries(n);\n  }\n\n  suiteRetries(n) {\n    this['[instance]'].setSuiteRetries(n);\n  }\n\n  define(name, value) {\n    this['[attributes]'][name] = value;\n\n    const isAttributeValid = Object.keys(Common.DEFAULT_ATTRIBUTES).includes(name) ||\n      Object.keys(Common.DEFAULT_ATTRIBUTES).includes(`@${name}`);\n\n    if (isAttributeValid) {\n      if (!name.startsWith('@')) {\n        name = `@${name}`;\n      }\n\n      return this['[instance]'].setAttribute(name, value);\n    }\n\n    // eslint-disable-next-line no-console\n    console.warn(`Attribute \"${name}\" is not a valid attribute. Valid attributes are: ${Object.keys(Common.DEFAULT_ATTRIBUTES).join(', ')}.`);\n  }\n}\n\nclass Describe extends Common {\n  constructor(instance, client = null) {\n    super(instance);\n\n    this.describeFn = null;\n    this.client = client;\n    this.describeInstance = null;\n    this.describeTitle = null;\n    this.instance.on('pre-require', (context) => this.createInterface(context));\n  }\n\n  createInstance(runOnly) {\n    if (!Utils.isFunction(this.describeFn)) {\n      throw new Error(`The describe/context must be a function. ${typeof this.describeFn} given.`);\n    }\n\n    const {describeTitle, instance, describeFn, client} = this;\n    this.describeInstance = new DescribeInstance({\n      describeTitle, instance, client\n    });\n\n    const {describeInstance} = this;\n    describeFn.call(describeInstance);\n\n    this.instance.setDescribeContext({describeTitle, describeInstance, runOnly});\n  }\n\n  /**\n   * Adds before, after, beforeEach, afterEach hooks to test suite\n   *\n   * @param context\n   */\n  addHooks(context) {\n    const hooksContext = Common.TestHooks.reduce((prev, hookName) => {\n      prev[hookName] = hookFn => {\n        this.instance.addTestHook(hookName, hookFn, this.describeInstance);\n      };\n\n      return prev;\n    }, {});\n\n    Object.assign(context, hooksContext);\n  }\n\n  addRun(context) {\n    context.run = function() {\n      // TODO: implement\n    };\n  }\n\n  createTestsuite({title, describeFn, context, runOnly = false}) {\n    this.describeFn = describeFn;\n    this.describeTitle = title;\n    if (this.describeFn) {\n      this.createInstance(runOnly);\n      const testsuite = require.cache[this.instance.modulePath];\n      if (testsuite && testsuite.exports) {\n        testsuite.exports['[@nightwatchDescribe]'] = true;\n      }\n    }\n  }\n\n  addDescribe(context) {\n    context.xmodule = {};\n    context.describe =\n      context.context = (title, describeFn) => {\n        this.createTestsuite({\n          context,\n          title,\n          describeFn\n        });\n      };\n\n    context.xdescribe =\n      context.xcontext =\n        context.describe.skip = (title, describeFn) => {\n          this.instance.once('module-loaded', () => {\n            // in case tests have been declared using other interfaces (e.g. exports),\n            // we do not want to disable the suite.\n            if (this.instance.tests.length === 0) {\n              // if no tests are added after all interfaces are loaded, disable the suite.\n              this.instance.setAttribute('@disabled', true);\n            }\n          });\n        };\n\n    context.describe.only = (title, describeFn) => {\n      this.createTestsuite({\n        title, describeFn, context, runOnly: true\n      });\n    };\n  }\n\n  addTest(context) {\n    context.it =\n    context.specify =\n    context.test = (testName, testFn) => {\n      this.instance.addTestCase({testName, testFn, describeInstance: this.describeInstance});\n    };\n\n    context.xit       =\n    context.xspecify  =\n    context.xtest     =\n    context.it.skip   =\n    context.test.skip = (testName) => {\n      this.instance.addTestCase({testName, testFn: function() {}, describeInstance: this.describeInstance, skipTest: true});\n    };\n\n    context.it.only =\n    context.specify.only =\n    context.test.only = (testName, testFn) => {\n      this.instance.addTestCase({testName, testFn, describeInstance: this.describeInstance, runOnly: true});\n    };\n  }\n\n  shouldReloadModuleCache() {\n    if (this.instance.shouldReloadModuleCache()) {\n      return true;\n    }\n\n    if (require.cache && require.cache[this.instance.modulePath]) {\n      const testsuiteModule = require.cache[this.instance.modulePath];\n      if (testsuiteModule.exports && testsuiteModule.exports['[@nightwatchDescribe]']) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  createInterface(context) {\n    // for suiteRetries to work with describe interface we need to re-require the file and clear the require cache\n    if (this.shouldReloadModuleCache()) {\n      delete require.cache[this.instance.modulePath];\n    }\n\n    this.addHooks(context);\n    this.addRun(context);\n    this.addDescribe(context);\n    this.addTest(context);\n  }\n}\n\nmodule.exports = Describe;\n"
  },
  {
    "path": "lib/testsuite/interfaces/exports.js",
    "content": "const Common = require('./common.js');\nconst Utils = require('../../utils');\n\nclass Exports extends Common {\n  get module() {\n    return this.instance.module;\n  }\n\n  constructor(instance) {\n    super(instance);\n\n    this.moduleKeys = null;\n    this.tests = null;\n    this.hooks = null;\n\n    this.instance.on('post-require', () => this.createInterface());\n  }\n\n  includeTestcase(item) {\n    return !Exports.TestHooks.includes(item) && (!this.currentTest || item === this.currentTest);\n  }\n\n  reduceKeys(testFn) {\n    return this.moduleKeys\n      .reduce((accumulator, item) => {\n        if (testFn(item)) {\n          accumulator.push(item);\n        }\n\n        return accumulator;\n      }, []);\n  }\n\n  addTestCase(testName) {\n    const testFn = this.module[testName];\n    this.instance.addTestCase({testName, testFn});\n  }\n\n  addTestHook(key) {\n    this.instance.addTestHook(key, this.module[key]);\n  }\n\n  loadHooks() {\n    this.hooks = this.reduceKeys(item => Exports.TestHooks.includes(item))\n      .map(key => this.addTestHook(key));\n  }\n\n  loadTests() {\n    this.tests = this.reduceKeys(item => this.includeTestcase(item))\n      .map(key => this.addTestCase(key));\n  }\n\n  createInterface() {\n    this.moduleKeys = Object.keys(this.module).filter(key => {\n      if (!this.module[key]) {\n        return false;\n      }\n\n      return Utils.isFunction(this.module[key]);\n    });\n\n    this.loadHooks();\n    this.loadTests();\n    this.readAttributes();\n  }\n\n  getAttribute(attrName) {\n    let value = this.module[attrName];\n    if (Utils.isUndefined(value)) {\n      value = this.module[attrName.substring(1)];\n\n      if (Utils.isUndefined(value)) {\n        value = this.instance.getAttribute(attrName);\n      }\n    }\n\n    return value;\n  }\n\n  readAttributes() {\n    const attributes = Object.keys(Common.DEFAULT_ATTRIBUTES).reduce((prev, key) => {\n      const value = this.getAttribute(key);\n      prev[key] = value !== undefined ? value : Common.DEFAULT_ATTRIBUTES[key];\n\n      return prev;\n    }, {});\n\n    this.instance.addAttributes(attributes);\n  }\n}\n\nmodule.exports = Exports;\n"
  },
  {
    "path": "lib/testsuite/nightwatch-inspector/index.js",
    "content": "const vm = require('vm');\nconst {crxfile} = require('@nightwatch/nightwatch-inspector');\nconst stripAnsi = require('strip-ansi');\nconst Debuggability = require('../../utils/debuggability');\nconst Utils = require('../../utils');\nconst WebSocket = require('./websocket-server.js');\nconst {Logger} = Utils;\n\nmodule.exports = class NightwatchInspectorServer extends WebSocket {\n  constructor(client) {\n    super();\n    this.client = client;\n    this.initSocket(this.playgroundWrapper.bind(this));\n    this.addExtensionInChromeOption();\n  }\n\n  /**\n   * Adds extensions capabilities to the Chrome options\n   */\n  addExtensionInChromeOption() {\n    const {desiredCapabilities} = this.client.settings;\n    const chromeOptions = desiredCapabilities['goog:chromeOptions'];\n    const {args = []} = chromeOptions || {};\n\n    desiredCapabilities['goog:chromeOptions'] = {\n      ...chromeOptions,\n      extensions: [crxfile],\n      args: [...args, '--auto-open-devtools-for-tabs']\n    };\n  }\n\n  //////////////////////////////////////////////////////////////////////////////////////////\n  // Commands Execution and Response\n  //////////////////////////////////////////////////////////////////////////////////////////\n\n  modifyCommandsResult(result, executedCommand, commandList) {\n    let error;\n\n    if (!result) {\n      result = 'Success';\n    } else if (Utils.isErrorObject(result) || result.error) {\n      result = result.message;\n      result = stripAnsi(result);\n      error = true;\n    }\n\n    return JSON.stringify({\n      result: result,\n      error: error,\n      executedCommand: executedCommand,\n      commandList: commandList\n    });\n  }\n\n  getNightwatchCommands() {\n    const {api} = this.client;\n    const {assert, expect, verify, ensure} = api;\n\n    return [\n      'browser',\n      ...[api, assert, expect, verify, ensure].reduce((keys, obj) => keys.concat(Object.keys(obj)), [])\n    ];\n  }\n\n  async executeCommands(data) {\n    let result;\n    const context = {browser: this.client.api};\n    const message = data.toString().replace('await ', '');\n\n    if (message === 'commandlist') {\n      const commandList = this.getNightwatchCommands();\n\n      return this.modifyCommandsResult(null, message, commandList);\n    }\n\n    try {\n      vm.createContext(context);\n\n      Logger.log('Executed from browser : ', message);\n      result = await vm.runInContext(message, context);\n    } catch (err) {\n      result = err;\n    }\n\n    return this.modifyCommandsResult(result, message);\n  }\n\n  async playgroundWrapper(data) {\n    const isES6AsyncTestcase = this.client.isES6AsyncTestcase;\n    Debuggability.debugMode = true;\n    this.client.isES6AsyncTestcase = true;\n\n    const result = await this.executeCommands(data);\n\n    this.client.isES6AsyncTestcase = isES6AsyncTestcase;\n    Debuggability.debugMode = false;\n\n    return result;\n  }\n};\n"
  },
  {
    "path": "lib/testsuite/nightwatch-inspector/websocket-server.js",
    "content": "const {WebSocketServer} = require('ws');\nconst Utils = require('../../utils');\nconst {Logger} = Utils;\n\nmodule.exports = class Websocket {\n  constructor() {\n    this.portNumber = 10096;\n  }\n\n  initSocket(cb) {\n    try {\n      this.startServer(cb);\n    } catch (e) {\n      this.handleSocketError(e, cb);\n    }\n  }\n\n  startServer(cb) {\n    this._wss = new WebSocketServer({host: 'localhost', port: this.portNumber});\n\n    this._wss.on('error', (error) => {\n      this.handleSocketError(error, cb);\n    });\n\n    this._wss.on('listening', () => {\n      Logger.log(`WebSocket server is listening on port ${this.portNumber}`);\n    });\n\n    this._wss.on('connection', (ws) => {\n      ws.on('message', async (data) => {\n        const result = await cb(data);\n        ws.send(result);\n      });\n    });\n  }\n\n  handleSocketError(e, cb) {\n    if (e.code === 'EADDRINUSE') {\n      Logger.warn(`Port ${this.portNumber} is already in use. Trying the next available port.`);\n      this.portNumber++;\n    } else {\n      Logger.error(`Could not start WebSocket server on port ${this.portNumber}: ${e.message}`);\n    }\n\n    this.initSocket(cb);\n  }\n\n  get nwsocket() {\n    return this._wss;\n  }\n\n  closeSocket() {\n    Logger.info(`Attempting to close websocket server running on port ${this.portNumber}...`);\n\n    this.nwsocket.close();\n  }\n};\n"
  },
  {
    "path": "lib/testsuite/repl.js",
    "content": "const repl = require('repl');\nconst {Logger} = require('../utils');\nconst vm = require('vm');\n\nmodule.exports = class NightwatchRepl {\n  constructor(config) {\n    this._config = Object.assign({\n      eval: this._eval.bind(this),\n      useGlobal: false, // so that REPL does not create a separate context to pass to eval.\n      preview: true,\n      timeout: 5500  // timeout for assertions is 5000 ms.\n    }, config);\n  }\n\n  static introMessage() {\n    return `\n  DEBUG MODE on...\n\n  Type any Nightwatch command to execute in the browser in real-time.\n  Try, ${Logger.colors.cyan('browser.navigateTo(\\'https://nightwatchjs.org\\');')}\n\n  (To exit, press Ctrl+C twice or type .exit)\n  `;\n  }\n\n  startServer(context) {\n    vm.createContext(context);\n    this._context = context;\n\n    // Start REPLServer\n    this._replServer = repl.start(this._config);\n  }\n\n  _eval(cmd, _, filename, callback) {\n    // Evaluate for output previews.\n    if (/^try { .+ } catch {}$/.test(cmd)) {\n      // if `cmd` represents a method call\n      if (cmd.includes('(')) {\n        return;\n      }\n\n      return this._outputPreview(cmd, callback);\n    }\n\n    // A command is already running whose result is awaited.\n    if (this._resultAwaited) {\n      return;\n    }\n\n    try {\n      const result = vm.runInContext(cmd, this._context);\n      this._handleResult(result, callback);\n    } catch (err) {\n      const errRegex = /^(Unexpected end of input|Unexpected token)/;\n      if (err.name === 'SyntaxError' && errRegex.test(err.message)) {\n        return callback(new repl.Recoverable(err));\n      }\n\n      Logger.error(err);\n      callback();\n    }\n  }\n\n  async _handleResult(result, callback) {\n    const resultIsPromise = result instanceof Promise || (result && typeof result.then === 'function');\n\n    if (!resultIsPromise) {\n      return callback(null, result);\n    }\n\n    this._resultAwaited = true;\n\n    let timeoutCalled = false;\n    const timeoutId = setTimeout(\n      () => {\n        this._resultAwaited = false;\n        timeoutCalled = true;\n        Logger.error('Timed out while waiting for response.');\n        callback();\n      },\n      this._config.timeout\n    );\n\n    try {\n      const res = await result;\n\n      if (timeoutCalled) {\n        return;\n      }\n\n      clearTimeout(timeoutId);\n      this._resultAwaited = false;\n      callback(null, res);\n    } catch (err) {\n      // When the promise is rejected, the error would have\n      // already been logged by Nightwatch.\n      // TODO: Should we close the REPL server here?\n\n      // Assertions errors would have already been logged\n      if (err.name !== 'NightwatchAssertError') {\n        Logger.error(err);\n      }\n\n      if (timeoutCalled) {\n        return;\n      }\n\n      clearTimeout(timeoutId);\n      this._resultAwaited = false;\n      callback();\n    }\n  }\n\n  _outputPreview(cmd, callback) {\n    const regex = /^try { (.+) } catch {}$/;\n    const match = cmd.match(regex);\n\n    if (match) {\n      const actualCmd = match[1];\n      const cmdArray = actualCmd.split('.');\n      try {\n        const result = cmdArray.reduce((prevCmd, currCmd) => {\n          return prevCmd[currCmd];\n        }, this._context);\n\n        return callback(null, result);\n      } catch (err) {\n        return;\n      }\n    }\n  }\n\n  onExit(callback) {\n    this._replServer.on('exit', callback);\n  }\n};\n"
  },
  {
    "path": "lib/testsuite/retries.js",
    "content": "class SuiteRetries {\n  constructor({retries = 0, suiteRetries = 0}) {\n    // testcase retries\n    this.testMaxRetries = retries;\n    this.testRetriesCount = {};\n\n    // suite retries\n    this.suiteMaxRetries = suiteRetries;\n    this.suiteRetriesCount = 0;\n  }\n\n  incrementTestRetriesCount(testName) {\n    this.testRetriesCount[testName] = this.testRetriesCount[testName] || 0;\n    this.testRetriesCount[testName]++;\n  }\n\n  incrementSuiteRetriesCount() {\n    this.suiteRetriesCount++;\n  }\n\n  shouldRetryTest(testName) {\n    if (this.testMaxRetries === 0) {\n      return false;\n    }\n\n    this.testRetriesCount[testName] = this.testRetriesCount[testName] || 0;\n\n    return this.testRetriesCount[testName] < this.testMaxRetries;\n  }\n\n  shouldRetrySuite() {\n    return this.suiteRetriesCount < this.suiteMaxRetries;\n  }\n}\n\nmodule.exports = SuiteRetries;\n"
  },
  {
    "path": "lib/testsuite/runnable.js",
    "content": "class Runnable {\n  constructor(name, runFn, opts = {}) {\n    this.name = name;\n    this.resolved = false;\n    this.deffered = {\n      settled: false,\n\n      /**\n       * @type {Promise}\n       */\n      promise: null,\n\n      /**\n       * @type {Function}\n       */\n      rejectFn: null,\n\n      /**\n       * @type {Function}\n       */\n      resolveFn: null,\n\n      name\n    };\n\n    this.isES6Async = opts.isES6Async;\n    this.createPromise();\n    this.setRunFn(runFn);\n  }\n\n  get runFn() {\n    return this.__runFn;\n  }\n\n  get currentPromise() {\n    if (!this.deffered.promise) {\n      return null;\n    }\n\n    return {\n      runnable: this.name,\n      resolve: this.deffered.resolveFn,\n      reject: this.deffered.rejectFn,\n      command: this.queue && this.queue.currentNode.name\n    };\n  }\n\n  setQueue(queue) {\n    this.queue = queue;\n    this.queue.reset();\n\n    return this;\n  }\n\n  /**\n   *\n   * @param {function} runFn\n   */\n  setRunFn(runFn) {\n    if (typeof runFn != 'function') {\n      throw new Error(`Runnable must be a function. \"${typeof runFn}\" given.`);\n    }\n\n    this.__runFn = runFn;\n\n    return this;\n  }\n\n  createPromise() {\n    this.deffered.promise = new Promise((resolve, reject) => {\n      this.deffered.resolveFn = (result) => {\n        if (!this.deffered.settled) {\n          resolve(result);\n        }\n\n        this.deffered.settled = true;\n      };\n\n      this.deffered.rejectFn = (err, force = false) => {\n        if (!this.deffered.settled || force) {\n          reject(err);\n        }\n\n        this.deffered.settled = true;\n      };\n    });\n\n    return this;\n  }\n\n  abort(err) {\n    return new Promise((resolve) => {\n      if (this.currentPromise && this.queueInProgress()) {\n        return this.deffered.promise.then(_ => resolve()).catch(_ => resolve());\n      }\n\n      resolve();\n    }).then(_ => {\n      this.currentPromise.reject(err, true);\n\n      return err;\n    });\n  }\n\n  setDoneCallback(cb) {\n    const originalResolve = this.deffered.resolveFn;\n    const originalReject = this.deffered.rejectFn;\n    this.deffered.resolveFn = function() {};\n    this.deffered.rejectFn = function() {};\n\n    return (result) => {\n      if (result instanceof Error) {\n        originalReject(result);\n      } else {\n        originalResolve(result);\n      }\n    };\n  }\n\n  run(queue = null) {\n    this.setQueue(queue);\n\n    let result;\n\n    try {\n      result = this.runFn();\n    } catch (err) {\n      this.deffered.rejectFn(err);\n\n      return this.deffered.promise;\n    }\n\n    if (result instanceof Promise) {\n      const deferredFn = () => {\n        result\n          .then(res_ => {\n            if (this.queueInProgress()) {\n              return;\n            }\n\n            this.deffered.resolveFn(res_);\n          })\n          .catch(err => {\n            this.deffered.rejectFn(err);\n          });\n      };\n\n      if (this.isES6Async) {\n        // the timeout is needed for situations where there is an async function without any await commands\n        setTimeout(() => deferredFn(), 20);\n\n        // without .catch() here, we can get an unhandledRejection\n        result\n          .catch(err => {\n            this.deffered.rejectFn(err);\n          });\n      } else {\n        deferredFn();\n      }\n    }\n\n    // `this.currentTestCaseResult` represents the return value of the currently\n    // running test case or hook.\n    // in case the runnable is executing something other than a test case/hook,\n    // `this.currentTestCaseResult` will be `undefined`.\n    if (this.currentTestCaseResult instanceof Promise) {\n      this.currentTestCaseResult\n        .catch(() => {\n          // to avoid unhandledRejections\n          // although the test case promises are already handled for rejections\n          // above (`result.catch()`), if we don't use `.catch()` here again,\n          // `.finally` will return a new promise that will be rejected without\n          // any error handling.\n        })\n        .finally(() => {\n          // mark the promise as settled as a cue to the asynctree so that it\n          // can get cleared out and subsequently call the queue `done` method.\n          this.currentTestCaseResult.settled = true;\n\n          // sometimes this promise is settled after the last call of\n          // asynctree `done` method, so we need schedule a tree traversal\n          // again to clear out the tree and call the queue `done` method.\n          this.queue.scheduleTraverse();\n        });\n    }\n\n    this.queue.run(this.currentTestCaseResult).then(err => {\n      if (err) {\n        return this.deffered.rejectFn(err);\n      }\n\n      this.deffered.resolveFn(result);\n    });\n\n    return this.deffered.promise;\n  }\n\n  queueInProgress() {\n    return this.queue.tree.inProgress;\n  }\n}\n\nmodule.exports = Runnable;\n"
  },
  {
    "path": "lib/testsuite/testcase.js",
    "content": "const BaseHook = require('./hooks/_basehook.js');\nconst {Logger} = require('../utils');\n\nclass UnitTest extends BaseHook {\n  get isGlobal() {\n    return true;\n  }\n\n  get isUnitTest() {\n    return true;\n  }\n\n  verifyMethod() {\n    return this.context.getKey(this.key) || null;\n  }\n}\n\nclass TestCase {\n  constructor(testName, {context, settings, reporter, options = {}}) {\n    this.testName = testName;\n    this.context = context;\n    this.reporter = reporter;\n    this.settings = settings;\n    this.retriesCount = options.retriesCount;\n    this.maxRetries = options.maxRetries;\n\n    this.print();\n    this.startTime = new Date().getTime();\n    this.reportKey = `${this.context.moduleKey}/${testName}`;\n  }\n\n  print() {\n    const {output, detailed_output} = this.settings;\n\n    if (output && detailed_output && !this.context.unitTestsMode) {\n      const {colors} = Logger;\n\n      if (this.retriesCount > 0) {\n        // eslint-disable-next-line no-console\n        console.log('Retrying (' + this.retriesCount + '/' + this.maxRetries + '): ', colors.red(this.testName));\n      } else {\n        this.reporter.logTestCase(this.testName);\n      }\n    }\n\n    return this;\n  }\n\n  run(client = null) {\n    this.client = client;\n\n    try {\n      let result;\n\n      if (this.context.unitTestsMode) {\n        result = this.runUnitTest();\n      } else {\n        result = this.context.call(this.testName, this.client);\n      }\n\n      return result;\n    } catch (err) {\n      return Promise.reject(err);\n    }\n\n  }\n\n  runUnitTest() {\n    let unitTest = new UnitTest(this.testName, this.context, {\n      asyncHookTimeout: this.settings.globals.unitTestsTimeout\n    });\n\n    return unitTest.run(this.client);\n  }\n}\n\nmodule.exports = TestCase;\n"
  },
  {
    "path": "lib/transport/errors/index.js",
    "content": "const ErrorCode = {\n  INSECURE_CERTIFICATE: 'insecure certificate',\n  ELEMENT_CLICK_INTERCEPTED: 'element click intercepted',\n  ELEMENT_IS_NOT_SELECTABLE: 'element not selectable',\n  ELEMENT_IS_NOT_INTERACTABLE: 'element not interactable',\n  INVALID_ARGUMENT: 'invalid argument',\n  INVALID_COOKIE_DOMAIN: 'invalid cookie domain',\n  INVALID_ELEMENT_COORDINATES: 'invalid coordinates',\n  INVALID_ELEMENT_STATE: 'invalid element state',\n  INVALID_SELECTOR: 'invalid selector',\n  NO_SUCH_SESSION: 'invalid session id',\n  JAVASCRIPT_ERROR: 'javascript error',\n  MOVE_TARGET_OUT_OF_BOUNDS: 'move target out of bounds',\n  NO_SUCH_ALERT: 'no such alert',\n  NO_SUCH_COOKIE: 'no such cookie',\n  NO_SUCH_ELEMENT: 'no such element',\n  NO_SUCH_FRAME: 'no such frame',\n  NO_SUCH_WINDOW: 'no such window',\n  SCRIPT_TIMEOUT: 'script timeout',\n  SESSION_NOT_CREATED_EXCEPTION: 'session not created',\n  STALE_ELEMENT_REFERENCE: 'stale element reference',\n  TIMEOUT: 'timeout',\n  UNABLE_TO_SET_COOKIE: 'unable to set cookie',\n  UNABLE_TO_CAPTURE_SCREEN: 'unable to capture screen',\n  UNEXPECTED_ALERT_OPEN: 'unexpected alert open',\n  UNKNOWN_COMMAND: 'unknown command',\n  UNKNOWN_ERROR: 'unknown error',\n  UNKNOWN_METHOD: 'unknown method',\n  UNSUPPORTED_OPERATION: 'unsupported operation'\n};\n\nconst Errors = {\n  [ErrorCode.UNEXPECTED_ALERT_OPEN]: {\n    message: 'A modal dialog was open, blocking this operation.'\n  },\n  [ErrorCode.SESSION_NOT_CREATED_EXCEPTION]: {\n    message: 'A new session could not be created.'\n  },\n  [ErrorCode.NO_SUCH_ALERT]: {\n    message: 'An attempt was made to operate on a modal dialog when one was not open.'\n  },\n  [ErrorCode.INVALID_ELEMENT_STATE]: {\n    message: 'An element command could not be completed because the element is in an invalid state (e.g. attempting to click an element that is no longer attached to the document).'\n  },\n  [ErrorCode.NO_SUCH_ELEMENT]: {\n    message: 'An element could not be located on the page using the given search parameters.',\n    help: [\n      'Please inspect the html before the step',\n      'Verify if an element with the mentioned selector is present in the DOM tree'\n    ]\n  },\n  [ErrorCode.JAVASCRIPT_ERROR]: {\n    message: 'An error occurred while executing user supplied JavaScript.'\n  },\n  [ErrorCode.UNKNOWN_ERROR]: {\n    message: 'An unknown server-side error occurred while processing the command.'\n  },\n  [ErrorCode.NO_SUCH_COOKIE]: {\n    message: 'No cookie matching the given path name was found amongst the cookies of the current active document.'\n  },\n  [ErrorCode.INSECURE_CERTIFICATE]: {\n    message: 'The SSL certificate running on this host cannot be validated. ' +\n      'If you wish to force accepting insecure SSL certificates, set acceptInsecureCerts=true in the ' +\n      'desiredCapabilities options.'\n  },\n  [ErrorCode.INVALID_ARGUMENT]: {\n    message: 'The arguments passed to the command are either invalid or malformed.'\n  },\n  [ErrorCode.INVALID_ARGUMENT]: {\n    message: 'The arguments passed to the command are either invalid or malformed.'\n  },\n  [ErrorCode.STALE_ELEMENT_REFERENCE]: {\n    message: 'The command failed because the referenced element is no longer attached to the DOM.'\n  },\n  [ErrorCode.INVALID_COOKIE_DOMAIN]: {\n    message: 'The cookie domain name is not valid for the current page.'\n  },\n  [ErrorCode.INVALID_ELEMENT_COORDINATES]: {\n    message: 'The coordinates provided to an interactions operation are invalid.'\n  },\n  [ErrorCode.ELEMENT_CLICK_INTERCEPTED]: {\n    message: 'The element click command could not be completed because another element is receiving the click event.'\n  },\n  [ErrorCode.TIMEOUT]: {\n    message: 'The operation did not complete before its timeout expired.'\n  },\n  [ErrorCode.UNABLE_TO_SET_COOKIE]: {\n    message: 'The request to set a cookie\\'s value could not be satisfied.'\n  },\n  [ErrorCode.UNKNOWN_METHOD]: {\n    message: 'The requested command matched a known URL but did not match a method for that URL.'\n  },\n  [ErrorCode.ELEMENT_IS_NOT_SELECTABLE]: {\n    message: 'The requested element cannot be selected.'\n  },\n  [ErrorCode.ELEMENT_IS_NOT_INTERACTABLE]: {\n    message: 'The requested element is not pointer or keyboard interactable.'\n  },\n  [ErrorCode.UNKNOWN_COMMAND]: {\n    message: 'The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource.'\n  },\n  [ErrorCode.UNABLE_TO_CAPTURE_SCREEN]: {\n    message: 'The screen capture failed.'\n  },\n  [ErrorCode.SCRIPT_TIMEOUT]: {\n    message: 'The script did not complete before its timeout expired.'\n  },\n  [ErrorCode.NO_SUCH_SESSION]: {\n    message: 'The session is either terminated or not started.'\n  },\n  [ErrorCode.NO_SUCH_FRAME]: {\n    message: 'The specified frame could not be found.',\n    help: [\n      'Please inspect the html before the step.',\n      'Verify if an iframe with the id is present in the DOM tree.'\n    ]\n  },\n  [ErrorCode.NO_SUCH_WINDOW]: {\n    message: 'The specified window could not be found.',\n    help: [\n      'Print existing window handles by using the command \"print driver.window_handles\".',\n      'Verify if the window name you have entered exists in the list.'\n    ]\n  },\n  [ErrorCode.INVALID_SELECTOR]: {\n    message: 'The supplied argument was an invalid selector (e.g. XPath/CSS).'\n  },\n  [ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS]: {\n    message: 'The target for mouse interaction is not in the browser\\'s viewport and cannot be brought into the viewport.'\n  },\n  [ErrorCode.UNSUPPORTED_OPERATION]: {\n    message: 'Unsupported operation exception.'\n  }\n};\n\nconst IosSessionErrors = {\n  SessionNotCreatedError: ErrorCode.SESSION_NOT_CREATED_EXCEPTION,\n  UnsupportedOperationError: ErrorCode.UNSUPPORTED_OPERATION\n};\n\nconst SeleniumNightwatchErrorCodeMap = {\n  NoSuchElementError: ErrorCode.NO_SUCH_ELEMENT\n};\n\nmodule.exports = {\n  findErrorById(statusCode) {\n    return {\n      status: statusCode,\n      id: statusCode,\n      message: Errors[statusCode].message\n    };\n  },\n\n  getErrorObject(err) {\n    if (err && (err.name in SeleniumNightwatchErrorCodeMap)) {\n      const statusCode = SeleniumNightwatchErrorCodeMap[err.name];\n\n      for (const [key, value] of Object.entries(Errors[statusCode])) {\n        err[key] ||= value;\n      }\n\n      err.id = statusCode;\n\n      return err;\n    } else if (err && err.name && (err.stack || err.stackTrace)){\n      return err;\n    }\n\n    if (err instanceof Error) {\n      return err;\n    }\n\n    let error;\n    if (typeof err == 'string') {\n      error = new Error(err);\n    } else if (err.error instanceof Error) {\n      return err.error;\n    }\n\n    error = error || new Error('unknown error');\n\n    return error;\n  },\n\n  StatusCode: ErrorCode,\n  Response: Errors,\n  IosSessionErrors: IosSessionErrors\n};\n"
  },
  {
    "path": "lib/transport/factory.js",
    "content": "const {Browser, Capabilities} = require('selenium-webdriver');\n\nconst BrowsersLowerCase = {\n  chrome: Browser.CHROME,\n  firefox: Browser.FIREFOX,\n  safari: Browser.SAFARI,\n  microsoftedge: Browser.EDGE,\n  msedge: Browser.EDGE,\n  edge: Browser.EDGE,\n  ie: Browser.INTERNET_EXPLORER,\n  'internet explorer': Browser.INTERNET_EXPLORER\n};\n\nmodule.exports = class TransportFactory {\n  static createSeleniumService(cliRunner) {\n    const usingAppium = cliRunner.test_settings.selenium.use_appium;\n\n    const Server = usingAppium\n      ? require('./selenium-webdriver/appium.js')\n      : require('./selenium-webdriver/selenium.js');\n\n    cliRunner.seleniumService = Server.createService(cliRunner.test_settings);\n    cliRunner.test_settings.selenium['[_started]'] = true;\n\n    return cliRunner.seleniumService.init();\n  }\n\n  static usingSeleniumServer(settings) {\n    if (!settings.selenium) {\n      return false;\n    }\n\n    let {start_process, host} = settings.selenium;\n    if (start_process) {\n      return true;\n    }\n\n    if (!host) {\n      host = settings.selenium_host || settings.seleniumHost;\n    }\n\n    return host && !settings.webdriver.start_process;\n  }\n\n  static adaptWebdriverSettings({settings, usingSeleniumServer = false}) {\n    if (!usingSeleniumServer && !(settings.capabilities instanceof Capabilities)) {\n      settings.capabilities = Object.assign({}, settings.desiredCapabilities);\n    }\n  }\n\n  static usingBrowserstackTurboScale(settings) {\n    return settings.webdriver.host && (settings.webdriver.host.endsWith('.browserstack-ats.com') || settings.webdriver.host.startsWith('browserstack-turboscale-grid'));\n  }\n\n  static usingBrowserstack(settings) {\n    return settings.webdriver.host && (settings.webdriver.host.endsWith('.browserstack.com') || TransportFactory.usingBrowserstackTurboScale(settings));\n  }\n\n  static getBrowserName(nightwatchInstance) {\n    const {settings, argv = {}} = nightwatchInstance;\n    const capabilities = settings.capabilities || settings.desiredCapabilities;\n    if (capabilities instanceof Capabilities) {\n      return capabilities.getBrowserName();\n    }\n\n    let {browserName} = settings.desiredCapabilities;\n\n    // Allow to use any browserName with Appium and BrowserStack.\n    // Not supporting '--browserName' cli flag for both of these.\n    const usingAppium = TransportFactory.usingSeleniumServer(settings) && settings.selenium.use_appium;\n    const usingBrowserStack = TransportFactory.usingBrowserstack(settings);\n    if (usingAppium || usingBrowserStack) {\n      if (BrowsersLowerCase[browserName && browserName.toLowerCase()]) {\n        browserName = BrowsersLowerCase[browserName.toLowerCase()];\n      }\n\n      return browserName;\n    }\n\n    // for backward compatibility\n    if (browserName === null) {\n      // eslint-disable-next-line no-console\n      console.warn('DEPRECATED: Setting browserName=null for running Appium tests has been deprecated ' +\n        'and will not be supported in future versions. Set `use_appium` property in `selenium` config to true ' +\n        'in your Nightwatch configuration file to run Appium tests.');\n\n      settings.selenium.use_appium = true;\n\n      return browserName;\n    }\n\n    if (argv.chrome) {\n      browserName = Browser.CHROME;\n    } else if (argv.firefox) {\n      browserName = Browser.FIREFOX;\n    } else if (argv.safari) {\n      browserName = Browser.SAFARI;\n    } else if (argv.edge) {\n      browserName = Browser.EDGE;\n    } else if (BrowsersLowerCase[browserName && browserName.toLowerCase()]) {\n      browserName = BrowsersLowerCase[browserName.toLowerCase()];\n    } else {\n      const didYouMean = require('didyoumean');\n      const browsersList = Object.values(Browser);\n      const resultMeant = didYouMean(browserName, browsersList);\n\n      throw new Error(`Unknown browser: \"${browserName}\"${resultMeant ? ('; did you mean \"' + resultMeant + '\"?') : ''}`);\n    }\n\n    return browserName;\n  }\n\n  static create(nightwatchInstance) {\n    const {settings} = nightwatchInstance;\n    const browserName = TransportFactory.getBrowserName(nightwatchInstance);\n    const usingSeleniumServer = TransportFactory.usingSeleniumServer(settings);\n\n    TransportFactory.adaptWebdriverSettings({settings, usingSeleniumServer});\n\n    return TransportFactory.createWebdriver(nightwatchInstance, {browserName, usingSeleniumServer});\n  }\n\n  static createWebdriver(nightwatchInstance, {usingSeleniumServer, browserName}) {\n    if (TransportFactory.usingBrowserstack(nightwatchInstance.settings)) {\n      if (!browserName) {\n        const AppAutomate = require('./selenium-webdriver/browserstack/appAutomate.js');\n\n        return new AppAutomate(nightwatchInstance, browserName);\n      }\n\n      if (TransportFactory.usingBrowserstackTurboScale(nightwatchInstance.settings)) {\n        const AutomateTurboScale = require('./selenium-webdriver/browserstack/automateTurboScale.js');\n\n        return new AutomateTurboScale(nightwatchInstance, browserName);\n      }\n\n      const Automate = require('./selenium-webdriver/browserstack/automate.js');\n\n      return new Automate(nightwatchInstance, browserName);\n    }\n\n    if (usingSeleniumServer) {\n      if (nightwatchInstance.settings.selenium.use_appium) {\n        const Appium = require('./selenium-webdriver/appium.js');\n\n        return new Appium(nightwatchInstance, browserName);\n      }\n\n      const Selenium = require('./selenium-webdriver/selenium.js');\n\n      return new Selenium(nightwatchInstance, browserName);\n    }\n\n    let Driver;\n    switch (browserName) {\n      case Browser.FIREFOX:\n        Driver = require('./selenium-webdriver/firefox.js');\n        break;\n\n      case Browser.CHROME:\n        Driver = require('./selenium-webdriver/chrome.js');\n        break;\n\n      case Browser.EDGE:\n        Driver = require('./selenium-webdriver/edge.js');\n        break;\n\n      case Browser.SAFARI:\n        Driver = require('./selenium-webdriver/safari.js');\n        break;\n\n      default:\n        throw new Error(`Unrecognized browser: ${browserName}.`);\n    }\n\n    return new Driver(nightwatchInstance);\n  }\n};\n"
  },
  {
    "path": "lib/transport/index.js",
    "content": "const EventEmitter = require('events');\n\nconst HttpRequest = require('../http/request.js');\nconst Factory = require('./factory.js');\nconst {Logger} = require('../utils');\n\nclass Transport extends EventEmitter {\n  static get DO_NOT_LOG_ERRORS() {\n    return [\n      'Unable to locate element',\n      '{\"errorMessage\":\"Unable to find element',\n      'no such element'\n    ];\n  }\n\n  get Errors() {\n    return require('./errors');\n  }\n\n  static create(nightwatchInstance) {\n    return Factory.create(nightwatchInstance);\n  }\n\n  /**\n   * Called once a test suite has finished executing\n   * @override\n   * @param {Error|Boolean} failures\n   * @returns {Promise<void>}\n   */\n  async testSuiteFinished(failures) {}\n\n  /**\n   * Called once a session has closed; a test suite can have multiple test cases and\n   *  hence multiple sessions can be started\n   * @override\n   * @returns {Promise<void>}\n   */\n  async sessionFinished() {}\n\n  isResultSuccess() {\n    return true;\n  }\n  /**\n   * Resolves the element ID based on the current transport used\n   *\n   * @param {Object} result\n   * @param {Element} element\n   * @param {Boolean} multipleElements\n   * @return {{value: *, status: number}|null}\n   */\n  resolveElement(result, element, multipleElements) {\n    if (!this.isResultSuccess(result)) {\n      return null;\n    }\n\n    let {value} = result;\n\n    if (multipleElements && Array.isArray(value) && value.length > 0) {\n      if (value.length > 1) {\n        let message = `More than one element (${value.length}) found for element <${element.toString()}> with selector: \"${element.selector}\".`;\n\n        if (this.settings.globals.throwOnMultipleElementsReturned) {\n          throw new Error(message);\n        }\n\n        if (!this.settings.globals.suppressWarningsOnMultipleElementsReturned) {\n          Logger.warn(`  Warning: ${message} Only the first one will be used.`);\n        }\n      }\n      value = value[0];\n    } else if (Array.isArray(value) && value.length === 0) {\n      value = null;\n    }\n\n    return value;\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  // Legacy Transport related\n  ////////////////////////////////////////////////////////////////////\n  /**\n   * Used when the error object is not parsed to its specific type (such as when using ChromeDriver with w3c:false)\n   *\n   */\n  getRetryableErrorMessages() {\n    const {StatusCode} = this.Errors;\n\n    const filtered = Object.keys(StatusCode)\n      .filter(key => [\n        'STALE_ELEMENT_REFERENCE',\n        'ELEMENT_CLICK_INTERCEPTED',\n        'INVALID_ELEMENT_STATE',\n        'ELEMENT_IS_NOT_INTERACTABLE'\n      ].includes(key))\n      .reduce((obj, key) => {\n        return {\n          ...obj,\n          [key]: StatusCode[key]\n        };\n      }, {});\n\n    return Object.values(filtered);\n  }\n\n  createHttpRequest(requestOptions) {\n    return new HttpRequest(requestOptions);\n  }\n\n  runProtocolAction(requestOptions) {\n    const request = this.createHttpRequest(requestOptions);\n\n    return new Promise((resolve, reject) => {\n      request\n        .on('success', (result, response) => {\n          if (result.error && result.status === -1) {\n            const errorResult = this.handleProtocolError(result, response);\n\n            return reject(errorResult);\n          }\n\n          resolve(result);\n        })\n        .on('error', (result, response, screenshotContent) => {\n          const errorResult = this.handleProtocolError(result, response, screenshotContent);\n\n          reject(errorResult);\n        })\n        .send();\n    });\n  }\n\n  sendHttpRequest(options) {\n    const request = this.createHttpRequest(options);\n\n    return new Promise((resolve, reject) => {\n      request\n        .on('success', (result, response) => {\n          resolve(result);\n        })\n        .on('error', (result, response) => {\n          reject(result);\n        })\n        .send();\n    });\n  }\n\n  handleProtocolError(result, response = {}) {\n    result = result || {};\n\n    const {status = '', value = null, error: errorResult, code = '', message = null} = result;\n    const {statusCode = null} = response;\n    let error;\n\n    // node.js errors\n    if (code && message) {\n      error = `Error ${code}: ${message}`;\n    } else {\n      // default error message;\n      error = response && response.statusCode === 404 ? 'Unknown command' : (errorResult || 'An unknown error has occurred.');\n    }\n\n    if (value && value.message) {\n      error = value.message;\n    } else if (value && value.error && this.Errors.Response[value.error]) {\n      error = this.Errors.Response[value.error].message;\n    }\n\n    if (!error && errorResult) {\n      error = errorResult;\n    }\n\n    return {\n      status: -1,\n      value,\n      code,\n      errorStatus: status,\n      error,\n      httpStatusCode: statusCode\n    };\n  }\n\n  getElementNotFoundResult(result) {\n    result.status = -1;\n    result.value = [];\n\n    let errorId = this.Errors.StatusCode && this.Errors.StatusCode.NO_SUCH_ELEMENT;\n    let errorInfo = this.Errors.findErrorById(errorId);\n\n    if (errorInfo) {\n      result.message = errorInfo.message;\n      result.errorStatus = errorInfo.status;\n    }\n\n    return result;\n  }\n\n  shouldRegisterError(result) {\n    let errorMessage = '';\n    if (result.value && result.value.message) {\n      errorMessage = result.value.message;\n    } else {\n      errorMessage = result.error || result.message;\n    }\n\n    const shouldIgnore = Transport.DO_NOT_LOG_ERRORS.some(function(item) {\n      return errorMessage.startsWith(item);\n    });\n\n    return !shouldIgnore;\n  }\n}\n\nmodule.exports = Transport;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/actions.js",
    "content": "const {error} = require('selenium-webdriver');\n\nconst {Logger, isObject, isFunction, isString} = require('../../utils');\nconst MethodMappings = require('./method-mappings.js');\n\nclass TransportActions {\n  get transport() {\n    return this.__transport;\n  }\n\n  get actions() {\n    return this.__actions;\n  }\n\n  get compatMode() {\n    return this.transport.settings.backwards_compatibility_mode;\n  }\n\n  constructor(transport) {\n    this.__transport = transport;\n    this.__actions = {};\n    this.lastError = null;\n    this.retriesCount = 0;\n    this.MethodMappings = new MethodMappings(transport);\n  }\n\n  loadActions(methodMappings = this.MethodMappings.methods, target = this.__actions) {\n    Object.keys(methodMappings).forEach(name => {\n      if (!methodMappings[name]) {\n        return;\n      }\n\n      if (isObject(methodMappings[name])) {\n        this.__actions[name] = this.__actions[name] || {};\n        this.loadActions(methodMappings[name], this.__actions[name]);\n      } else {\n        target[name] = this.createAction(name, methodMappings[name]);\n      }\n    });\n  }\n\n  createAction(name, mapping) {\n    return async (definition) => {\n      const args = definition.args;\n      let result;\n      let promise;\n\n      try {\n        if (isFunction(mapping)) {\n          promise = Array.isArray(args) ? mapping.apply(this.MethodMappings, args) : mapping.call(this.MethodMappings, args);\n        }\n\n        if (!(promise instanceof Promise)) {\n          const opts = {};\n\n          if (isString(promise)) {\n            opts.path = `/session/${definition.sessionId}${promise}`;\n          } else if (isObject(promise)) {\n            Object.assign(opts, promise);\n            if (isFunction(opts.path)) {\n              opts.path = await opts.path();\n            }\n            opts.path = `/session/${definition.sessionId}${opts.path}`;\n          }\n\n          promise = this.transport.runProtocolAction(opts);\n        }\n\n        result = await promise;\n\n        return this.makeResult(result);\n      } catch (err) {\n        const error = this.handleError(err, name);\n\n        return {\n          error,\n          status: -1,\n          value: null\n        };\n      }\n    };\n  }\n\n  makeResult(result) {\n    this.transport.handleErrorResponse(result);\n\n    if (Array.isArray(result) || !isObject(result)) {\n      return {\n        value: result,\n        status: 0\n      };\n    }\n\n    result.status = result.status || 0;\n\n    return result;\n  }\n\n  handleError(err, commandName) {\n    let errorMsg = 'Unknown error';\n    try {\n      this.transport.handleErrorResponse(err);\n    } catch (error) {\n      if (!error.message) {\n        if (isString(err.value)) {\n          error.message = err.value;\n        } else if (isString(err.error)) {\n          error.message = err.error;\n        } else {\n          error.message = 'Unknown error';\n        }\n      }\n\n      err = error;\n    }\n\n    if (err instanceof Error) {\n      errorMsg = err.message;\n    } else if (err && err.error) {\n      errorMsg = err.error;\n    }\n\n    const {shouldRegisterError} = this.transport;\n    const {lastError, retriesCount} = this;\n    if (shouldRegisterError(err) && (retriesCount < 1 || lastError && err.name !== lastError.name)) {\n      Logger.error(`Error while running .${commandName}() protocol action: ${errorMsg}\\n`);\n      this.lastError = err;\n    }\n    if (this.lastError && err.name === this.lastError.name) {\n      this.retriesCount += 1;\n    }\n\n    if (err instanceof Error) {\n      err.message = errorMsg;\n\n      return err;\n    }\n\n    return new error.WebDriverError(errorMsg);\n  }\n}\n\nmodule.exports = TransportActions;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/appium.js",
    "content": "const AppiumBaseServer = require('./appiumBase.js');\nconst AppiumServiceBuilder = require('./service-builders/appium.js');\nconst {iosRealDeviceUDID} = require('../../utils/mobile.js');\n\n\nclass AppiumServer extends AppiumBaseServer {\n  static createService(settings) {\n    const Options = require('./options.js');\n    const opts = new Options({settings});\n    opts.updateWebdriverPath();\n\n    const appiumService = new AppiumServiceBuilder(settings);\n\n    const outputFile = settings.webdriver.log_file_name || '';\n    appiumService.setOutputFile(outputFile);\n\n    return appiumService;\n  }\n\n  get defaultBrowser() {\n    return null;\n  }\n\n  get ServiceBuilder() {\n    return AppiumServiceBuilder;\n  }\n\n  get defaultServerUrl() {\n    return 'http://127.0.0.1:4723';\n  }\n\n  get defaultPort() {\n    return 4723;\n  }\n\n  get defaultPathPrefix() {\n    return '/wd/hub';\n  }\n\n  createSessionOptions(argv) {\n    this.extractAppiumOptions();\n\n    // set 'appium:udid' if deviceId present in argv\n    if (argv && argv.deviceId) {\n      const platformName = this.desiredCapabilities.platformName;\n\n      let udid = argv.deviceId;\n      if (platformName && platformName.toLowerCase() === 'ios') {\n        udid = iosRealDeviceUDID(udid);\n      }\n\n      this.desiredCapabilities['appium:udid'] = udid;\n    }\n\n    // if `appium:chromedriverExecutable` is present and left blank,\n    // assign the path of binary from `chromedriver` NPM package to it.\n    if (this.desiredCapabilities['appium:chromedriverExecutable'] === '') {\n      const chromedriver = this.seleniumCapabilities.getChromedriverPath();\n      if (chromedriver) {\n        this.desiredCapabilities['appium:chromedriverExecutable'] = chromedriver;\n      }\n    }\n\n    return super.createSessionOptions(argv) || this.desiredCapabilities;\n  }\n\n  createDriver({options}) {\n    return this.createAppiumDriver({options});\n  }\n};\n\nmodule.exports = AppiumServer;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/appiumBase.js",
    "content": "const {WebDriver} = require('selenium-webdriver');\nconst {Executor} = require('selenium-webdriver/http');\nconst http = require('selenium-webdriver/http');\nconst SeleniumServer = require('./selenium.js');\nconst {isObject} = require('../../utils');\n\n\nclass AppiumBaseServer extends SeleniumServer {\n  extractAppiumOptions() {\n    // break 'appium:options' to individual configs\n    if (isObject(this.desiredCapabilities['appium:options'])) {\n      const appiumOptions = this.desiredCapabilities['appium:options'];\n      for (let key of Object.keys(appiumOptions)) {\n        const value = appiumOptions[key];\n\n        if (!key.startsWith('appium:')) {\n          key = `appium:${key}`;\n        }\n        this.desiredCapabilities[key] = value;\n      }\n\n      delete this.desiredCapabilities['appium:options'];\n    }\n  }\n\n  createAppiumDriver({options}) {\n    const httpClient = new http.HttpClient(this.getServerUrl());\n\n    return WebDriver.createSession(new Executor(httpClient), options);\n  }\n};\n\nmodule.exports = AppiumBaseServer;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/browserstack/appAutomate.js",
    "content": "const path = require('path');\nconst Utils = require('../../../utils');\nconst BrowserStack = require('./browserstack.js');\n\nconst {Logger} = Utils;\n\nclass AppAutomate extends BrowserStack {\n  get ApiUrl() {\n    return `https://api.browserstack.com/${this.productNamespace}`;\n  }\n\n  get productNamespace() {\n    return 'app-automate';\n  }\n\n  async createSessionOptions() {\n    this.extractAppiumOptions();\n\n    const options = this.desiredCapabilities;\n    if (options && (options.appUploadUrl || options.appUploadPath)) {\n      await this.uploadAppToBrowserStack(options);\n    }\n\n    return options;\n  }\n\n  async uploadAppToBrowserStack(options) {\n    const {appUploadPath, appUploadUrl} = options;\n\n    const multiPartFormData = {};\n    if (appUploadPath) {\n      multiPartFormData['file'] = {\n        filePath: path.resolve(appUploadPath)\n      };\n    } else if (appUploadUrl) {\n      multiPartFormData['url'] = {\n        data: appUploadUrl\n      };\n    }\n\n    if (options['appium:app'] && !options['appium:app'].startsWith('bs://')) {\n      multiPartFormData['custom_id'] = {\n        data: options['appium:app']\n      };\n    }\n\n    // eslint-disable-next-line no-console\n    console.log(Logger.colors.stack_trace(`Uploading app to BrowserStack from '${appUploadPath || appUploadUrl}'...`));\n\n    try {\n      const response = await this.sendHttpRequest({\n        url: 'https://api-cloud.browserstack.com/app-automate/upload',\n        method: 'POST',\n        use_ssl: true,\n        port: 443,\n        auth: {\n          user: this.username,\n          pass: this.accessKey\n        },\n        multiPartFormData\n      });\n\n      if (response.error) {\n        const errMessage = 'App upload to BrowserStack failed. Original error: ' + response.error;\n\n        throw new Error(errMessage);\n      }\n\n      if (!response.app_url) {\n        const errMessage = 'App upload was unsuccessful. Got response: ' + response;\n\n        throw new Error(errMessage);\n      }\n\n      // eslint-disable-next-line no-console\n      console.log(Logger.colors.green(Utils.symbols.ok), Logger.colors.stack_trace('App upload successful!'), '\\n');\n\n      if (!response.custom_id) {\n        // custom_id not being used\n        options['appium:app'] = response.app_url;\n\n        // to display url when test suite is finished\n        this.uploadedAppUrl = response.app_url;\n      }\n    } catch (err) {\n      err.help = [];\n\n      if (appUploadPath) {\n        err.help.push('Check if you have entered correct file path in \\'appUploadPath\\' desired capability.');\n      } else if (appUploadUrl) {\n        err.help.push('Check if you have entered correct publicly available file URL in \\'appUploadUrl\\' desired capability.');\n      }\n\n      if (err.message.includes('BROWSERSTACK_INVALID_CUSTOM_ID')) {\n        err.help.push('Check if \\'appium:app\\' or \\'appium:options\\' > app desired capability is correctly set to BrowserStack app url or required custom ID.');\n      }\n\n      err.help.push(\n        'See BrowserStack app-upload docs for more details: https://www.browserstack.com/docs/app-automate/api-reference/appium/apps#upload-an-app',\n        'More details on setting custom ID for app: https://www.browserstack.com/docs/app-automate/appium/upload-app-define-custom-id'\n      );\n\n      Logger.error(err);\n\n      throw err;\n    }\n  }\n\n  createDriver({options}) {\n    return this.createAppiumDriver({options});\n  }\n}\n\nmodule.exports = AppAutomate;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/browserstack/automate.js",
    "content": "const BrowserStack = require('./browserstack.js');\nconst {Capabilities} = require('selenium-webdriver');\n\nclass Automate extends BrowserStack {\n  get ApiUrl() {\n    return `https://api.browserstack.com/${this.productNamespace}`;\n  }\n\n  get productNamespace() {\n    return 'automate';\n  }\n\n  createDriver({options = this.desiredCapabilities}) {\n    if (options instanceof Capabilities) {\n      return super.createDriver({options});\n    }\n\n    return this.createAppiumDriver({options});\n  }\n}\n\nmodule.exports = Automate;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/browserstack/automateTurboScale.js",
    "content": "const stripAnsi = require('strip-ansi');\nconst Automate = require('./automate.js');\n\nclass AutomateTurboScale extends Automate {\n  get buildUrl() {\n    return `https://${this.productNamespace}.browserstack.com/dashboard`;\n  }\n\n  get ApiUrl() {\n    return 'https://api.browserstack.com/automate-turboscale/v1';\n  }\n\n  get productNamespace() {\n    return 'grid';\n  }\n\n  get buildsListingApiUrl() {\n    // https://www.browserstack.com/docs/automate-turboscale/api-reference/build#get-build-list\n    return `${this.ApiUrl}/builds`;\n  }\n\n  findBuildHashId(buildsResponse) {\n    const builds = buildsResponse?.builds;\n    if (!builds || builds.length === 0) {\n      return false;\n    }\n\n    const currentBuild = builds.find((item) => item.name === this.build);\n    if (currentBuild) {\n      return currentBuild.hashed_id;\n    }\n  }\n\n  async sendReasonToBrowserstack(isFailure = false, reason = '') {\n    const sessionDetails = await this.sendHttpRequest({\n      url: `${this.ApiUrl}/sessions/${this.sessionId}`,\n      method: 'GET',\n      use_ssl: true,\n      port: 443,\n      auth: {\n        user: this.username,\n        pass: this.accessKey\n      }\n    });\n\n    const status = sessionDetails?.status;\n    if (['passed', 'failed'].includes(status)) {\n      // status has already been set by user\n      return;\n    }\n\n    reason = stripAnsi(reason);\n    await this.sendHttpRequest({\n      url: `${this.ApiUrl}/sessions/${this.sessionId}`,\n      method: 'PATCH',\n      use_ssl: true,\n      port: 443,\n      data: {\n        status: isFailure ? 'failed' : 'passed',\n        reason\n      },\n      auth: {\n        user: this.username,\n        pass: this.accessKey\n      }\n    });\n  }\n}\n\nmodule.exports = AutomateTurboScale;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/browserstack/browserstack.js",
    "content": "const stripAnsi = require('strip-ansi');\nconst {Logger} = require('../../../utils');\nconst AppiumBaseServer = require('../appiumBase.js');\nconst defaultsDeep = require('lodash/defaultsDeep');\n\n\nclass Browserstack extends AppiumBaseServer {\n  bStackOptions() {\n    return this.settings.desiredCapabilities['bstack:options'];\n  }\n\n  get buildUrl() {\n    return `https://${this.productNamespace}.browserstack.com`;\n  }\n\n  get buildsListingApiUrl() {\n    // https://www.browserstack.com/docs/automate/api-reference/selenium/build#get-build-list\n    return `${this.ApiUrl}/builds.json`;\n  }\n\n  get accessKey() {\n    return this.bStackOptions().accessKey;\n  }\n\n  get username() {\n    return this.bStackOptions().userName;\n  }\n\n  get build() {\n    return this.bStackOptions().buildName;\n  }\n\n  get local() {\n    return this.bStackOptions().local;\n  }\n\n  constructor(nightwatchInstance, browserName) {\n    super(nightwatchInstance, browserName);\n\n    this.useLocal = false;\n\n    this.nightwatchInstance.on('nightwatch:session.create', (data) => {\n      this.sessionId = data.sessionId;\n      this.getBuildId().then(buildId => {\n        if (buildId) {\n          this.buildId = buildId;\n        }\n      });\n    });\n  }\n\n  findBuildHashId(buildsResponse) {\n    if (!buildsResponse || buildsResponse.length === 0) {\n      return false;\n    }\n\n    const currentBuild = buildsResponse.find((item) => item.automation_build?.name === this.build);\n    if (currentBuild) {\n      return currentBuild.automation_build?.hashed_id;\n    }\n  }\n\n  adaptSettings() {\n    this.settings.webdriver.start_process = false;\n    this.settings.webdriver.port = Number(this.settings.webdriver.port);\n\n    const {desiredCapabilities} = this.settings;\n\n    // checking for legacy-ways for providing config\n    this.settings.desiredCapabilities['bstack:options'] = defaultsDeep(this.settings.desiredCapabilities['bstack:options'], {\n      userName: desiredCapabilities['browserstack.user'],\n      accessKey: desiredCapabilities['browserstack.key'],\n      buildName: desiredCapabilities.build || desiredCapabilities.buildName,\n      local: desiredCapabilities['browserstack.local'],\n      sessionName: desiredCapabilities['name']\n    });\n\n    if (!this.accessKey && process.env.BROWSERSTACK_KEY) {\n      this.settings.desiredCapabilities['bstack:options'].accessKey = process.env.BROWSERSTACK_KEY;\n    }\n\n    if (!this.username && process.env.BROWSERSTACK_USER) {\n      this.settings.desiredCapabilities['bstack:options'].userName = process.env.BROWSERSTACK_USER;\n    }\n\n    if (!this.build) {\n      this.settings.desiredCapabilities['bstack:options'].buildName = 'nightwatch-test-build';\n    }\n\n    if (this.local) {\n      this.useLocal = true;\n    }\n  }\n\n  verifySettings() {\n    if (this.settings.webdriver.port !== 443) {\n      // eslint-disable-next-line no-console\n      console.warn(Logger.colors.brown('Using insecure HTTP connection on port 80. Consider using SSL by ' +\n        'setting port to 443 in your Nightwatch configuration.'));\n    }\n\n    if (!this.accessKey) {\n      throw new Error('BrowserStack access key is not set. Verify that \"browserstack.key\" capability is set correctly or ' +\n        'set BROWSERSTACK_KEY environment variable (.env files are supported).');\n    }\n\n    if (!this.username) {\n      throw new Error('BrowserStack username is not set. Verify that \"browserstack.user\" capability is set correctly or ' +\n        'set BROWSERSTACK_USER environment variable (.env files are supported).');\n    }\n  }\n\n  createSession({argv, moduleKey}) {\n    this.adaptSettings();\n    this.verifySettings();\n\n    return super.createSession({argv, moduleKey});\n  }\n\n  async getBuildId() {\n    try {\n      let offset = 0;\n\n      while (offset <= 100) {\n        const builds = await this.sendHttpRequest({\n          url: `${this.buildsListingApiUrl}?status=running&limit=20&offset=${offset}`,\n          method: 'GET',\n          use_ssl: true,\n          port: 443,\n          auth: {\n            user: this.username,\n            pass: this.accessKey\n          }\n        });\n\n        const buildHashId = this.findBuildHashId(builds);\n        if (buildHashId) {\n          return buildHashId; // Return the matched hashed_id\n        }\n        if (buildHashId === false) {\n          // No builds returned by API, exit the loop\n          break;\n        }\n\n        offset += 20;\n      }\n    } catch (err) {\n      console.error(err);\n    }\n  }\n\n  async sendReasonToBrowserstack(isFailure = false, reason = '') {\n    const sessionDetails = await this.sendHttpRequest({\n      url: `${this.ApiUrl}/sessions/${this.sessionId}.json`,\n      method: 'GET',\n      use_ssl: true,\n      port: 443,\n      auth: {\n        user: this.username,\n        pass: this.accessKey\n      }\n    });\n\n    const status = sessionDetails?.automation_session?.status;\n    if (['passed', 'failed'].includes(status)) {\n      // status has already been set by user\n      return;\n    }\n\n    reason = stripAnsi(reason);\n    await this.sendHttpRequest({\n      url: `${this.ApiUrl}/sessions/${this.sessionId}.json`,\n      method: 'PUT',\n      use_ssl: true,\n      port: 443,\n      data: {\n        status: isFailure ? 'failed' : 'passed',\n        reason\n      },\n      auth: {\n        user: this.username,\n        pass: this.accessKey\n      }\n    });\n  }\n\n  async sessionFinished(reason, err) {\n    super.sessionFinished(reason);\n    await this.testSuiteFinished(err);\n  }\n\n  async testSuiteFinished(err) {\n    try {\n      if (this.sessionId) {\n        const reason = err instanceof Error ? `${err.name}: ${err.message}` : '';\n        await this.sendReasonToBrowserstack(!!err, reason);\n        // eslint-disable-next-line no-console\n        console.log('\\n  ' + 'See more info, video, & screenshots on Browserstack:\\n' +\n          '  ' + Logger.colors.light_cyan(`${this.buildUrl}/builds/${this.buildId}/sessions/${this.sessionId}`));\n      }\n\n      if (this.uploadedAppUrl) {\n        // App was uploaded to BrowserStack and custom_id not being used\n        // eslint-disable-next-line no-console\n        console.log('\\n  ' + Logger.colors.light_cyan(\n          `Please set 'appium:app' capability to '${this.uploadedAppUrl}' to avoid uploading the app again in future runs.`\n        ) + '\\n');\n      }\n\n      this.sessionId = null;\n\n      return true;\n    } catch (err) {\n      Logger.error(err);\n\n      return false;\n    }\n  }\n}\n\nmodule.exports = Browserstack;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/cdp.js",
    "content": "class Cdp {\n  async getConnection(driver, reset = false) {\n    if (!reset && this._connection) {\n      return this._connection;\n    }\n\n    return this._connection = await driver.createCDPConnection('page');\n  }\n\n  resetConnection() {\n    this._connection = undefined;\n    this._networkMocks = undefined;\n  }\n\n  get networkMocks() {\n    if (this._networkMocks) {\n      return this._networkMocks;\n    }\n\n    return this._networkMocks = {};\n  }\n\n  addNetworkMock(url, response) {\n    this.networkMocks[url] = response;\n  }\n}\n\nmodule.exports = new Cdp();\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/chrome.js",
    "content": "const {Browser} = require('selenium-webdriver');\nconst SeleniumWebdriver = require('./');\n\nmodule.exports = class ChromeDriver extends SeleniumWebdriver {\n  get ServiceBuilder() {\n    return require('./service-builders/chrome.js');\n  }\n\n  setBuilderOptions({builder, options}) {\n    if (this.driverService) {\n      const {service} = this.driverService;\n\n      builder\n        .forBrowser(Browser.CHROME)\n        .setChromeService(service);\n    } else {\n      const serverUrl = this.getServerUrl();\n\n      builder\n        .usingServer(serverUrl)\n        .withCapabilities(this.initialCapabilities);\n    }\n\n    return super.setBuilderOptions({builder, options});\n  }\n};\n\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/edge.js",
    "content": "const {Browser} = require('selenium-webdriver');\nconst SeleniumWebdriver = require('./');\n\nmodule.exports = class ChromeDriver extends SeleniumWebdriver {\n  get ServiceBuilder() {\n    return require('./service-builders/edge.js');\n  }\n\n  setBuilderOptions({builder, options}) {\n    if (this.driverService) {\n      const {service} = this.driverService;\n\n      builder\n        .forBrowser(Browser.EDGE)\n        .setEdgeService(service);\n    } else {\n      const serverUrl = this.getServerUrl();\n\n      builder\n        .usingServer(serverUrl)\n        .withCapabilities(this.initialCapabilities);\n    }\n\n    return super.setBuilderOptions({builder, options});\n  }\n};\n\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/firefox.js",
    "content": "const {Browser} = require('selenium-webdriver');\nconst SeleniumWebdriver = require('./');\n\nmodule.exports = class GeckoDriver extends SeleniumWebdriver {\n  get ServiceBuilder() {\n    return require('./service-builders/firefox.js');\n  }\n\n  setBuilderOptions({builder, options}) {\n    if (this.driverService) {\n      const {service} = this.driverService;\n\n      builder\n        .forBrowser(Browser.FIREFOX)\n        .setFirefoxService(service);\n    } else {\n      const serverUrl = this.getServerUrl();\n\n      builder\n        .usingServer(serverUrl)\n        .withCapabilities(this.initialCapabilities);\n    }\n\n    return super.setBuilderOptions({builder, options});\n  }\n};\n\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/httpclient.js",
    "content": "const HttpRequest = require('../../http/request.js');\n\nmodule.exports = function(settings, HttpResponse) {\n  // TODO: handle agent and proxy arguments below\n  const url = require('url');\n\n  return class HttpClient {\n    constructor(serverUrl, opt_agent, opt_proxy) {\n      this.agent_ = opt_agent || null;\n      // eslint-disable-next-line\n      const options = url.parse(serverUrl);\n      if (!options.hostname) {\n        throw new Error('Invalid URL: ' + serverUrl);\n      }\n      this.proxyOptions_ = opt_proxy ? {} : null;\n\n      const {hostname: host, pathname: path, protocol} = options;\n      const {log_screenshot_data} = settings;\n      let {port} = options;\n      if (port) {\n        port = Number(port);\n        HttpRequest.updateGlobalSettings({port});\n      } else {\n        port = protocol === 'https' ? 443 : 80;\n      }\n\n      this.options = {\n        host,\n        port,\n        path,\n        addtOpts: {\n          suppressBase64Data: !log_screenshot_data\n        },\n        use_ssl: protocol === 'https:'\n      };\n      this.errorTimeoutId = null;\n\n    }\n\n    /** @override */\n    send(httpRequest) {\n      const {method, data, path} = httpRequest;\n      const headers = {};\n\n      if (httpRequest.headers) {\n        httpRequest.headers.forEach(function (value, name) {\n          headers[name] = value;\n        });\n      }\n\n      this.options.headers = headers;\n      this.options.data = data;\n      this.options.path = path;\n      this.options.method = method;\n\n      const request = new HttpRequest(this.options);\n\n      return new Promise((resolve, reject) => {\n        request.once('success', (data, response, isRedirect) => {\n          const {statusCode, headers} = response;\n          let body = '';\n          if (data) {\n            try {\n              body = JSON.stringify(data);\n            } catch (err) {\n              //\n            }\n          }\n\n          if (data && data.error) {\n            reject(data);\n          } else {\n            const resp = new HttpResponse(statusCode, headers, body);\n            resolve(resp);\n          }\n        });\n\n        request.on('error', (err) => {\n          let {message, code} = err;\n\n          // for connection reset errors, sometimes the error event gets fired multiple times\n          if (this.errorTimeoutId) {\n            clearTimeout(this.errorTimeoutId);\n          }\n          this.errorTimeoutId = setTimeout(() => {\n            if (code) {\n              message = code + ' ' + message;\n            }\n\n            const error = new Error(message);\n            if (code) {\n              error.code = code;\n            }\n\n            reject(error);\n          }, 15);\n        });\n\n        request.send();\n      });\n    }\n  };\n};\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/index.js",
    "content": "const ora = require('ora');\nconst {Builder, Browser, error} = require('selenium-webdriver');\n\nconst Actions = require('./actions.js');\nconst SeleniumCapabilities = require('./options.js');\nconst {Logger, isObject} = require('../../utils');\nconst {IosSessionNotCreatedError, AndroidConnectionError} = require('../../utils/mobile.js');\nconst httpClient = require('./httpclient.js');\nconst Session = require('./session.js');\nconst BaseTransport = require('../');\nconst {colors} = Logger;\nconst {isErrorResponse, checkLegacyResponse, throwDecodedError, WebDriverError} = error;\nconst {IosSessionErrors} = require('../errors');\n\nlet _driverService = null;\nlet _driver = null;\n\nclass Transport extends BaseTransport {\n  /**\n   * @param {Builder} builder\n   * @param {Capabilities} options\n   */\n  static setBuilderOptions({builder, options}) {\n    switch (options.getBrowserName()) {\n      case Browser.CHROME:\n        builder.setChromeOptions(options);\n        break;\n\n      case Browser.FIREFOX:\n        builder.setFirefoxOptions(options);\n        break;\n\n      case Browser.SAFARI:\n        builder.setSafariOptions(options);\n        break;\n\n      case Browser.EDGE:\n        builder.setEdgeOptions(options);\n        break;\n\n      case Browser.OPERA:\n        // TODO: implement\n        break;\n\n      case Browser.INTERNET_EXPLORER:\n        builder.setIeOptions(options);\n        break;\n    }\n  }\n\n  static get driver() {\n    return _driver;\n  }\n\n  static set driver(value) {\n    _driver = value;\n  }\n\n  static get driverService() {\n    return _driverService;\n  }\n\n  static set driverService(value) {\n    _driverService = value;\n  }\n\n\n  /**\n   * @override\n   */\n  get ServiceBuilder() {\n    return null;\n  }\n\n  get defaultPort() {\n    return this.ServiceBuilder ? this.ServiceBuilder.defaultPort : 4444;\n  }\n\n  get Actions() {\n    return this.actionsInstance.actions;\n  }\n\n  get reporter() {\n    return this.nightwatchInstance.reporter;\n  }\n\n  get api() {\n    return this.nightwatchInstance.api;\n  }\n\n  get settings() {\n    return this.nightwatchInstance.settings;\n  }\n\n  get desiredCapabilities() {\n    return this.settings.desiredCapabilities;\n  }\n\n  get defaultPathPrefix() {\n    return '';\n  }\n\n  get outputEnabled() {\n    return this.settings.output;\n  }\n\n  get usingSeleniumServer() {\n    return this.settings.selenium && this.settings.selenium.start_process;\n  }\n\n  get shouldStartDriverService() {\n    return this.settings.webdriver.start_process;\n  }\n\n  get serviceName() {\n    return this.ServiceBuilder.serviceName;\n  }\n\n  get elementKey() {\n    return this.__elementKey || Session.WEB_ELEMENT_ID;\n  }\n\n  get initialCapabilities() {\n    return this.seleniumCapabilities.initialCapabilities;\n  }\n\n  get parallelMode() {\n    return this.settings.testWorkersEnabled;\n  }\n\n  constructor(nightwatchInstance, {isSelenium = false, browserName} = {}) {\n    super(nightwatchInstance);\n\n    this.nightwatchInstance = nightwatchInstance;\n    this.browserName = browserName;\n\n    this.seleniumCapabilities = new SeleniumCapabilities({\n      settings: this.settings,\n      browserName\n    });\n\n    this.createHttpClient();\n    this.createActions();\n  }\n\n  /**\n   * @override\n   */\n  setBuilderOptions({options, builder}) {\n    Transport.setBuilderOptions({options, builder});\n  }\n\n  createActions() {\n    this.actionsInstance = new Actions(this);\n    this.actionsInstance.loadActions();\n  }\n\n  createHttpClient() {\n    const http = require('selenium-webdriver/http');\n    http.HttpClient = httpClient(this.settings, http.Response);\n  }\n\n  getServerUrl() {\n    if (this.shouldStartDriverService) {\n      return this.defaultServerUrl;\n    }\n\n    return this.settings.webdriver.url;\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  // Session related\n  ////////////////////////////////////////////////////////////////////\n  async closeDriver() {\n    if (this.driverService) {\n      try {\n        await this.driverService.stop();\n        this.driverService = null;\n        this.stopped = true;\n      } catch (err) {\n        Logger.error(err);\n        err.displayed = true;\n\n        throw err;\n      }\n    }\n  }\n\n  async sessionFinished(reason) {\n    this.emit('session:finished', reason);\n\n    await this.closeDriver();\n  }\n\n  async createDriverService({options, moduleKey, reuseBrowser = false}) {\n    try {\n      moduleKey = this.settings.webdriver.log_file_name || moduleKey || '';\n\n      if (!this.shouldReuseDriverService(reuseBrowser)) {\n        Transport.driverService = new this.ServiceBuilder(this.settings);\n        await Transport.driverService.setOutputFile(reuseBrowser ? 'test' : moduleKey).init(options);\n      }\n\n      this.driverService = Transport.driverService;\n    } catch (err) {\n      this.showConnectSpinner(colors.red(`Failed to start ${this.serviceName}.`), 'warn');\n\n      throw err;\n    }\n  }\n\n  shouldReuseDriverService(reuseBrowser) {\n    return (Transport.driverService && !Transport.driverService.stopped && reuseBrowser);\n  }\n\n\n\n\n  async getDriver({options, reuseBrowser = false}) {\n    const value  = await this.shouldReuseDriver(reuseBrowser);\n    if (value) {\n      return Transport.driver;\n    }\n\n    Transport.driver = await this.createDriver({options});\n\n    return Transport.driver;\n  }\n\n\n  async shouldReuseDriver(reuseBrowser) {\n    if (!reuseBrowser || !Transport.driver) {\n      return false;\n    }\n    try {\n      await Transport.driver.getSession();\n\n      return true;\n    } catch (err) {\n      return false;\n    }\n  }\n\n  /**\n   * @param {Capabilities} options\n   * @returns {Builder}\n   */\n  createSessionBuilder(options) {\n    const builder = new Builder();\n    builder.disableEnvironmentOverrides();\n\n    this.setBuilderOptions({builder, options});\n\n    return builder;\n  }\n\n  createSessionOptions(argv) {\n    return this.seleniumCapabilities.create(argv);\n  }\n\n  createDriver({options}) {\n    const builder = this.createSessionBuilder(options);\n\n    this.builder = builder;\n\n    return builder.build();\n  }\n\n  async createSession({argv, moduleKey, reuseBrowser = false}) {\n    const startTime = new Date();\n    const {host, port, start_process} = this.settings.webdriver;\n    const portStr = port ? `port ${port}` : 'auto-generated port';\n    const options = await this.createSessionOptions(argv);\n\n    if (start_process) {\n      if (this.usingSeleniumServer) {\n        options.showSpinner = (msg) => {\n          this.showConnectSpinner(msg);\n        };\n      } else {\n        this.showConnectSpinner(`Starting ${this.serviceName} on ${portStr}...\\n`);\n      }\n\n      await this.createDriverService({options, moduleKey, reuseBrowser});\n    } else {\n      this.showConnectSpinner(`Connecting to ${host} on ${portStr}...\\n`);\n    }\n\n    try {\n      this.driver = await this.getDriver({options, reuseBrowser});\n\n      const session = new Session(this.driver);\n      const sessionExports = await session.exported();\n      const {sessionInfo, sessionId, capabilities, elementKey} = sessionExports;\n\n      this.__elementKey = elementKey;\n      await this.showConnectInfo({startTime, host, port, start_process, sessionInfo});\n\n      return {\n        sessionId,\n        capabilities,\n        host,\n        port\n      };\n    } catch (err) {\n      const error = this.handleConnectError(err, host, port);\n      this.showConnectSpinner(colors.red(`Failed to connect to ${this.serviceName} on ${host} with ${colors.stack_trace(portStr)}.`), 'warn');\n\n      throw error;\n    }\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  // Output related\n  ////////////////////////////////////////////////////////////////////\n  async showConnectInfo({startTime, port, host, start_process, sessionInfo}) {\n    if (!this.parallelMode) {\n      this.showConnectSpinner(`Connected to ${colors.stack_trace(start_process ? this.serviceName : host)} on port ${colors.stack_trace(port)} ${colors.stack_trace('(' + (new Date() - startTime) + 'ms)')}.`);\n    }\n\n    if (this.outputEnabled) {\n      const {platform, browserVersion, platformVersion, browserName, appId} = sessionInfo;\n\n      const appName = appId.split('.').pop() || browserName;\n      const appVersion = browserVersion && ` (${browserVersion})`;\n      const platName = platform.toUpperCase();\n      const platVersion = platformVersion && ` (${platformVersion})`;\n\n      // eslint-disable-next-line no-console\n      console.info(`  Using: ${colors.light_blue(appName)}${colors.brown(appVersion)} on ${colors.cyan(platName + platVersion)}.\\n`);\n    }\n  }\n\n  showConnectSpinner(msg, method = 'info') {\n    if (!this.outputEnabled || this.parallelMode) {\n      return;\n    }\n\n    if (this.connectSpinner) {\n      this.connectSpinner[method](msg);\n    } else {\n      this.connectSpinner = ora(msg).start();\n    }\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  // Elements related\n  ////////////////////////////////////////////////////////////////////\n  getElementId(resultValue) {\n    return resultValue[this.elementKey];\n  }\n\n  toElement(resultValue) {\n    return {[this.elementKey]: resultValue};\n  }\n\n  mapWebElementIds(value) {\n    if (Array.isArray(value)) {\n      return value.reduce((prev, item) => {\n        prev.push(this.getElementId(item));\n\n        return prev;\n      }, []);\n    }\n\n    return value;\n  }\n\n  /**\n   * Helper method\n   *\n   * @param {String} protocolAction\n   * @param {Object} executeArgs\n   * @return {Promise}\n   */\n  executeProtocolAction(protocolAction, executeArgs) {\n    if (isObject(protocolAction) && protocolAction.actionName) {\n      const {actionName, args, sessionId = this.nightwatchInstance.sessionId} = protocolAction;\n\n      return this.Actions.session[actionName]({\n        args,\n        sessionId,\n        sessionRequired: true\n      });\n    }\n\n    return this.Actions.session[protocolAction]({\n      args: executeArgs,\n      sessionId: this.nightwatchInstance.sessionId,\n      sessionRequired: true\n    });\n  }\n\n  ////////////////////////////////////////////////////////////////////\n  // Error handling\n  ////////////////////////////////////////////////////////////////////\n  handleErrorResponse(result) {\n    if (isErrorResponse(result)) {\n      // will throw error if w3c response\n      throwDecodedError(result);\n\n      // will throw error if legacy response\n      checkLegacyResponse(result);\n    }\n  }\n\n  registerLastError(err, retryCount = 0) {\n    this.lastError = err;\n    this.retriesCount = retryCount;\n  }\n\n  getErrorMessage(result) {\n    if (result instanceof Error) {\n      return result.message;\n    }\n\n    return result.value && result.value.message;\n  }\n\n  handleConnectError(err, host, port) {\n    const errMsg = `An error occurred while creating a new ${this.serviceName} session:`;\n\n    switch (err.code) {\n      case 'ECONNREFUSED':\n        err.sessionCreate = true;\n        err.message = `${errMsg} Connection refused to ${host}:${port}. If the Webdriver/Selenium service is managed by Nightwatch, check if \"start_process\" is set to \"true\".`;\n        break;\n      default:\n        err.message = `${errMsg} [${err.name}] ${err.message}`;\n    }\n\n    if (!err.detailedErr && this.driverService) {\n      const logPath = this.driverService.getOutputFilePath();\n      err.detailedErr = ` Verify if ${this.serviceName} is configured correctly; using:\\n  ${this.driverService.getSettingsFormatted()}\\n`;\n      err.extraDetail = (logPath ? `\\n  More info might be available in the log file: ${logPath}` : `\\n  Set webdriver.log_path in your Nightwatch config to retrieve more logs from ${this.serviceName}.`);\n\n      if (err.message.includes('Failed to run adb command') || err.message.includes('no devices online')) {\n        return new AndroidConnectionError(err);\n      }\n\n      if (IosSessionErrors[err.name] && this.api.isSafari() && this.api.isIOS()) {\n        return new IosSessionNotCreatedError(err, this.desiredCapabilities);\n      }\n    }\n\n    err.showTrace = false;\n    err.reportShown = true;\n\n    return err;\n  }\n\n  isResultSuccess(result = {}) {\n    return !(\n      (result instanceof Error) ||\n      (result.error instanceof Error) ||\n      result.status === -1\n    );\n  }\n\n  getOutputFilePath() {\n    return this.driverService.getOutputFilePath();\n  }\n\n  getErrorResponse(result) {\n    return result instanceof Error ? result : result.error;\n  }\n\n  staleElementReference(result) {\n    return result instanceof error.StaleElementReferenceError;\n  }\n\n  elementClickInterceptedError(result) {\n    return result instanceof error.ElementClickInterceptedError;\n  }\n\n  invalidElementStateError(result) {\n    return result instanceof error.InvalidElementStateError;\n  }\n\n  elementNotInteractableError(result) {\n    return result instanceof error.ElementNotInteractableError;\n  }\n\n  invalidWindowReference(result) {\n    return result instanceof error.NoSuchWindowError;\n  }\n\n  invalidSessionError(result) {\n    return result instanceof error.NoSuchSessionError;\n  }\n\n  isRetryableElementError(result) {\n    const errorResponse = this.getErrorResponse(result);\n\n    if (errorResponse instanceof WebDriverError && errorResponse.name === 'WebDriverError') {\n      const errors = this.getRetryableErrorMessages();\n\n      return errors.some(item => errorResponse.message.includes(item));\n    }\n\n    return (\n      this.staleElementReference(errorResponse) ||\n      this.elementClickInterceptedError(errorResponse) ||\n      this.invalidElementStateError(errorResponse) ||\n      this.elementNotInteractableError(errorResponse)\n    );\n  }\n}\n\nmodule.exports = Transport;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/method-mappings.js",
    "content": "const {WebElement, WebDriver, Origin, By, until, Condition, Key} = require('selenium-webdriver');\nconst {ShadowRoot} = require('selenium-webdriver/lib/webdriver');\nconst {Locator} = require('../../element');\nconst NightwatchLocator = require('../../element/locator-factory.js');\nconst {isString} = require('../../utils');\nconst fs = require('fs');\nconst cdp = require('./cdp.js');\n\nmodule.exports = class MethodMappings {\n  get driver() {\n    return this.transport.driver;\n  }\n\n  get settings() {\n    return this.transport.settings;\n  }\n\n  getWebElement(webElementOrString) {\n    if (webElementOrString && (webElementOrString.webElement instanceof WebElement)) {\n      webElementOrString = webElementOrString.webElement;\n    }\n\n    if (webElementOrString instanceof WebElement) {\n      return webElementOrString;\n    }\n\n    if (isString(webElementOrString)) {\n      return new WebElement(this.driver, webElementOrString);\n    }\n\n    throw new Error(`Unknown element: ${webElementOrString}`);\n  }\n\n  async runScriptForElement(scriptFn, webElementOrId) {\n    const element = this.getWebElement(webElementOrId);\n    const parentElementId = await element.getId();\n    const {elementKey} = this.transport;\n\n    return this.driver.executeScript(scriptFn, {[elementKey]: parentElementId});\n  }\n\n  async getElementByJs(scriptFn, webElementOrId) {\n    try {\n      const result = await this.runScriptForElement(scriptFn, webElementOrId);\n\n      if (!result) {\n        return {\n          value: null,\n          status: 0\n        };\n      }\n\n      const {elementKey} = this.transport;\n      const elementId = await result.getId();\n\n      const returnValue = {\n        value: {\n          [elementKey]: elementId\n        },\n        status: 0,\n        elementId\n      };\n\n      Object.assign(returnValue.value, {\n        get getId() {\n          return function () {\n            return elementId;\n          };\n        }\n      });\n\n      return returnValue;\n    } catch (error) {\n      if (error.name === 'NoSuchElementError') {\n        return {\n          status: 0,\n          value: null\n        };\n      }\n\n      throw error;\n    }\n  }\n\n  constructor(transport) {\n    this.transport = transport;\n  }\n\n  executeFn(fn, name, args) {\n    if (!Array.isArray(args)) {\n      args = [args];\n    }\n\n    return this.driver[name](fn, ...args);\n  }\n\n  get methods() {\n    return {\n      ///////////////////////////////////////////////////////////\n      // Session related\n      ///////////////////////////////////////////////////////////\n      async sessionAction(action) {\n        switch (action) {\n          case 'DELETE': {\n            await this.driver.quit();\n\n            return {\n              state: 'success',\n              value: null\n            };\n          }\n\n          default:\n            return this.driver.getSession();\n        }\n      },\n\n      getSessions() {\n        return '/sessions';\n      },\n\n      getStatus() {\n        return '/status';\n      },\n\n      session: {\n        ///////////////////////////////////////////////////////////\n        // Timeouts\n        ///////////////////////////////////////////////////////////\n        async setTimeoutType(type, value) {\n          await this.driver.manage().setTimeouts({\n            [type]: value\n          });\n\n          return null;\n        },\n\n        async setTimeoutsAsyncScript(value) {\n          await this.driver.manage().setTimeouts({script: value});\n\n          return null;\n        },\n\n        async setTimeoutsImplicitWait(value) {\n          await this.driver.manage().setTimeouts({implicit: value});\n\n          return null;\n        },\n\n        getTimeouts() {\n          return this.driver.manage().getTimeouts();\n        },\n\n        ///////////////////////////////////////////////////////////\n        // Session log\n        ///////////////////////////////////////////////////////////\n        async getSessionLogTypes() {\n          const value = await this.driver.manage().logs().getAvailableLogTypes();\n\n          return {\n            value\n          };\n        },\n\n        async getLogContents(type) {\n          const value = await this.driver.manage().logs().get(type);\n\n          return {\n            value: value.map(item => {\n              return {\n                level: {\n                  value: item.level.value,\n                  name: item.level.name\n                },\n                type: item.type,\n                timestamp: item.timestamp,\n                message: item.message\n              };\n            })\n          };\n        },\n\n        ///////////////////////////////////////////////////////////\n        // Navigation\n        ///////////////////////////////////////////////////////////\n        async navigateTo(url) {\n          await this.driver.navigate().to(url);\n\n          return null;\n        },\n\n        async getCurrentUrl() {\n          const url = await this.driver.getCurrentUrl();\n\n          return url;\n        },\n\n        async navigateBack() {\n          await this.driver.navigate().back();\n\n          return null;\n        },\n\n        async navigateForward() {\n          await this.driver.navigate().forward();\n\n          return null;\n        },\n\n        async pageRefresh() {\n          await this.driver.navigate().refresh();\n\n          return null;\n        },\n\n        async getPageTitle() {\n          const title = await this.driver.getTitle();\n\n          return title;\n        },\n\n        ///////////////////////////////////////////////////////////\n        // Windows\n        ///////////////////////////////////////////////////////////\n        async switchToWindow(windowHandle) {\n          await this.driver.switchTo().window(windowHandle);\n\n          return null;\n        },\n\n        async closeWindow() {\n          await this.driver.close();\n\n          return null;\n        },\n\n        /**\n         * @returns {string}\n         */\n        async getWindowHandle() {\n          const value = await this.driver.getWindowHandle();\n\n          return value;\n        },\n\n        async getAllWindowHandles() {\n          const value = await this.driver.getAllWindowHandles();\n\n          return {\n            value\n          };\n        },\n\n        async getWindowPosition() {\n          const {x, y} = await this.driver.manage().window().getRect();\n\n          return {\n            value: {\n              x,\n              y\n            }\n          };\n        },\n\n        async maximizeWindow() {\n          await this.driver.manage().window().maximize();\n\n          return null;\n        },\n\n        async minimizeWindow() {\n          await this.driver.manage().window().minimize();\n\n          return null;\n        },\n\n        async fullscreenWindow() {\n          await this.driver.manage().window().fullscreen();\n\n          return null;\n        },\n\n        async openNewWindow(type = 'tab') {\n          await this.driver.switchTo().newWindow(type);\n\n          return null;\n        },\n\n        async setWindowPosition(x, y) {\n          await this.driver.manage().window().setRect({\n            x,\n            y\n          });\n\n          return {\n            value: null\n          };\n        },\n\n        async getWindowSize(windowHandle) {\n          const value = await this.driver.manage().window().getRect();\n\n          // For backward compatibility\n          if (windowHandle !== undefined) {\n            return {\n              value\n            };\n          }\n\n          const {width, height} = value;\n\n          return {\n            value: {\n              width,\n              height\n            }\n          };\n        },\n\n        async setWindowSize(width, height) {\n          await this.driver.manage().window().setRect({\n            width,\n            height\n          });\n\n          return {\n            value: null\n          };\n        },\n\n        async getWindowRect() {\n          const value = await this.driver.manage().window().getRect();\n\n          return {\n            value\n          };\n        },\n\n        async setWindowRect(data) {\n          await this.driver.manage().window().setRect(data);\n\n          return {\n            value: null\n          };\n        },\n        ///////////////////////////////////////////////////////////\n        // Frames\n        ///////////////////////////////////////////////////////////\n        async switchToFrame(frameId) {\n          if (frameId === undefined) {\n            frameId = null;\n          }\n\n          await this.driver.switchTo().frame(frameId);\n\n          return {\n            value: null\n          };\n        },\n\n        async switchToParentFrame() {\n          await this.driver.switchTo().parentFrame();\n\n          return {\n            value: null\n          };\n        },\n\n        ///////////////////////////////////////////////////////////\n        // Elements\n        ///////////////////////////////////////////////////////////\n        async locateSingleElement(element) {\n          const locator = NightwatchLocator.create(element, this.transport.api.isAppiumClient());\n          const webElement = await this.driver.findElement(locator);\n          const elementId = await webElement.getId();\n\n          const {elementKey} = this.transport;\n\n          return {\n            value: {[elementKey]: elementId}\n          };\n        },\n\n        async locateMultipleElements(element) {\n          const locator = NightwatchLocator.create(element, this.transport.api.isAppiumClient());\n          const resultValue = await this.driver.findElements(locator);\n\n          if (Array.isArray(resultValue) && resultValue.length === 0) {\n            return {\n              status: -1,\n              value: [],\n              error: 'no such element',\n              message: `Unable to locate element: ${locator.value} using ${locator.using}`\n            };\n          }\n\n          const {elementKey} = this.transport;\n          const value = await Promise.all(resultValue.map(async webElement => {\n            const elementId = await webElement.getId();\n\n            return {[elementKey]: elementId};\n          }));\n\n          return value;\n        },\n\n\n        elementIdEquals(id, otherId) {\n          return `/element/${id}/equals/${otherId}`;\n        },\n\n        async locateSingleElementByElementId({id, using, value}) {\n          const locator = Locator.create({using, value});\n          const element = await this.getWebElement(id);\n          const webElement = await element.findElement(locator);\n          const elementId = await webElement.getId();\n\n          const {elementKey} = this.transport;\n\n          return {\n            value: {[elementKey]: elementId},\n            status: 0,\n            elementId\n          };\n        },\n\n        async locateMultipleElementsByElementId({id, using, value}) {\n          const locator = Locator.create({using, value});\n          const element = await this.getWebElement(id);\n          const resultValue = await element.findElements(locator);\n\n          const {elementKey} = this.transport;\n          const resultProcessed = await Promise.all(resultValue.map(async webElement => {\n            const elementId = await webElement.getId();\n\n            return {[elementKey]: elementId};\n          }));\n\n          return resultProcessed;\n        },\n\n        async getActiveElement() {\n          const webElement = await this.driver.switchTo().activeElement();\n          const elementId = await webElement.getId();\n\n          return elementId;\n        },\n\n        getElementAttribute(webElementOrId, attributeName) {\n          if (this.transport.api.isAppiumClient()) {\n            return `/element/${webElementOrId}/attribute/${attributeName}`;\n          }\n\n          const element = this.getWebElement(webElementOrId);\n\n          return element.getAttribute(attributeName);\n        },\n\n        async getElementAccessibleName(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          const elementAccessibleName = await element.getAccessibleName();\n\n          return elementAccessibleName;\n        },\n\n        async getElementAriaRole(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          const elementAriaRole = await element.getAriaRole();\n\n          return elementAriaRole;\n        },\n\n        async takeElementScreenshot(webElementOrId, scroll) {\n          const element = this.getWebElement(webElementOrId);\n          const screenshotData = await element.takeScreenshot(scroll);\n\n          return screenshotData;\n        },\n\n        async getElementCSSValue(webElementOrId, cssPropertyName) {\n          const element = this.getWebElement(webElementOrId);\n          const elementCssValue = await element.getCssValue(cssPropertyName);\n\n          return elementCssValue;\n        },\n\n        async getElementProperty(webElementOrId, propertyName) {\n          const element = this.getWebElement(webElementOrId);\n          const elementValue = await element.getProperty(propertyName);\n\n          return {\n            value: elementValue\n          };\n        },\n\n        async isElementActive(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          const elementId = await element.getId();\n\n          const currentActiveElementId = await this.methods.session.getActiveElement.call(this);\n\n          return elementId === currentActiveElementId;\n        },\n\n        async setElementProperty(webElementOrId, name, value) {\n          const element = this.getWebElement(webElementOrId);\n\n          await this.driver.executeScript(function (element, name, value) {\n            element[name] = value;\n          }, element, name, value);\n        },\n\n        async setElementAttribute(webElement, attrName, value) {\n          const element = this.getWebElement(webElement);\n\n          // eslint-disable-next-line\n          /* istanbul ignore next */const fn = function (e, a, v) { try { if (e && typeof e.setAttribute == 'function') { e.setAttribute(a, v); } return true; } catch (err) { return { error: err.message, message: err.name + ': ' + err.message }; } };\n          const elementId = await element.getId();\n\n          const result = await this.driver.executeScript('var passedArgs = Array.prototype.slice.call(arguments,0); ' +\n            'return (' + fn.toString() + ').apply(window, passedArgs);', {[this.transport.elementKey]: elementId}, attrName, value);\n\n          return result;\n        },\n\n        async getElementTagName(id) {\n          const element = this.getWebElement(id);\n          const elementTagName = await element.getTagName();\n\n          return elementTagName;\n        },\n\n        async getElementRect(id) {\n          const element = this.getWebElement(id);\n\n          try {\n            const value = await element.getRect();\n\n            return {\n              value\n            };\n          } catch (error) {\n            error.message = `Unable to get element rect because of: ${error.message}`;\n\n            return {\n              error,\n              status: -1,\n              value: null\n            };\n          }\n        },\n\n        async getElementText(id) {\n          const element = this.getWebElement(id);\n          const elementText = await element.getText();\n\n          return elementText;\n        },\n\n        // the value param is compulsory\n        async getElementValue(webElementOrId, value) {\n          const element = this.getWebElement(webElementOrId);\n          const elementValue = await element.getAttribute(value);\n\n          return elementValue;\n        },\n\n        isElementLocationInView(id) {\n          return `/element/${id}/location_in_view`;\n        },\n\n        isElementDisplayed(webElementOrId) {\n          if (this.transport.api.isAppiumClient()) {\n            return `/element/${webElementOrId}/displayed`;\n          }\n\n          const element = this.getWebElement(webElementOrId);\n\n          return element.isDisplayed();\n        },\n\n        async isElementEnabled(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          const value = await element.isEnabled();\n\n          return value;\n        },\n\n        async isElementSelected(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          const value = await element.isSelected();\n\n          return value;\n        },\n\n        async isElementPresent(webElement) {\n          // webElement would be a Promise in case of new Element API.\n          const element = await webElement;\n\n          return element instanceof WebElement || element instanceof ShadowRoot;\n        },\n\n        async clearElementValue(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          await element.clear();\n\n          try {\n            const value = await element.getProperty('value');\n            if (isString(value) && value.length > 0) {\n              const backArr = Array(value.length).fill(Key.BACK_SPACE);\n              await element.sendKeys(...backArr);\n            }\n          } catch {\n            // silent catch\n          }\n\n          return null;\n        },\n\n        setElementValueRedacted(webElementOrId, value) {\n          const modifiedValue = [Key.NULL].concat(value);\n\n          return this.methods.session.setElementValue.call(this, webElementOrId, modifiedValue);\n        },\n\n        async checkElement(webElementOrId) {\n          const element = await this.getWebElement(webElementOrId);\n          const elementType = await element.getAttribute('type');\n          const checkableTypes = ['checkbox', 'radio'];\n\n          if (!checkableTypes.includes(elementType)) {\n            throw new Error('must be an input element with type attribute \\'checkbox\\' or \\'radio\\'');\n          }\n\n          const value = await element.isSelected();\n\n          if (!value) {\n            await element.click();\n          }\n\n          return null;\n        },\n\n        async uncheckElement(webElementOrId) {\n          const element = await this.getWebElement(webElementOrId);\n          const elementType = await element.getAttribute('type');\n          const checkableTypes = ['checkbox', 'radio'];\n\n          if (!checkableTypes.includes(elementType)) {\n            throw new Error('must be an input element with type attribute \\'checkbox\\' or \\'radio\\'');\n          }\n\n          const value = await element.isSelected();\n\n          if (value) {\n            await element.click();\n          }\n\n          return null;\n        },\n\n        async setElementValue(webElementOrId, value) {\n          if (Array.isArray(value)) {\n            value = value.join('');\n          } else {\n            value = String(value);\n          }\n\n          const element = this.getWebElement(webElementOrId);\n\n          // clear Element value\n          try {\n            await this.methods.session.clearElementValue.call(this, webElementOrId);\n          } catch (err) {\n            if (err.name !== 'InvalidElementStateError') {\n              throw err;\n            }\n          }\n          await element.sendKeys(value);\n\n          return null;\n        },\n\n        async sendKeysToElement(webElementOrId, value) {\n          if (Array.isArray(value)) {\n            if (value.includes(undefined) || value.includes(null)) {\n              throw TypeError('each key must be a number or string; got ' + value);\n            }\n            value = value.join('');\n          }\n\n          const element = this.getWebElement(webElementOrId);\n\n          await element.sendKeys(value);\n\n          return null;\n        },\n\n        async uploadFile(webElementOrId, filepath) {\n          const remote = require('selenium-webdriver/remote');\n          this.driver.setFileDetector(new remote.FileDetector());\n\n          const element = this.getWebElement(webElementOrId);\n          await element.sendKeys(filepath);\n\n          return {\n            value: null\n          };\n        },\n\n        async clickElement(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          await element.click();\n\n          return null;\n        },\n\n        async clickElementWithJS(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          await this.driver.executeScript('arguments[0].click();', element);\n\n          return null;\n        },\n\n        async elementSubmit(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          await element.submit();\n\n          return null;\n        },\n\n        sendKeys(keys) {\n          return {\n            method: 'POST',\n            path: '/keys',\n            data: {\n              value: keys\n            }\n          };\n        },\n\n        async getFirstElementChild(webElementOrId) {\n          return await this.getElementByJs(function (element) {\n            return element && element.firstElementChild;\n          }, webElementOrId);\n        },\n\n        /**\n         * @param {WebElement} webElement\n         */\n        inspectInDevTools(webElement, content = 'Element') {\n          return this.driver.executeScript(function (element, content) {\n            // eslint-disable-next-line no-console\n            console.log(content + ':', element);\n          }, webElement, content);\n        },\n\n        async getLastElementChild(webElementOrId) {\n          return await this.getElementByJs(function (element) {\n            return element && element.lastElementChild;\n          }, webElementOrId);\n        },\n\n        async getNextSibling(webElementOrId) {\n          return await this.getElementByJs(function (element) {\n            return element && element.nextElementSibling;\n          }, webElementOrId);\n        },\n\n        async getPreviousSibling(webElementOrId) {\n          return await this.getElementByJs(function (element) {\n            return element && element.previousElementSibling;\n          }, webElementOrId);\n        },\n\n        async getShadowRoot(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          const shadowRoot = await element.getShadowRoot();\n\n          return shadowRoot;\n        },\n\n        async elementHasDescendants(webElementOrId) {\n          const count = await this.runScriptForElement(function (element) {\n            return element ? element.childElementCount : null;\n          }, webElementOrId);\n\n          if (count === null) {\n            throw new Error('No such element: ' + webElementOrId);\n          }\n\n          return count > 0;\n        },\n\n        ///////////////////////////////////////////////////////////\n        // Document Handling\n        ///////////////////////////////////////////////////////////\n        async getPageSource() {\n          const value = await this.driver.getPageSource();\n\n          return value;\n        },\n\n        async executeScript(script, args) {\n          const value = await this.executeFn(script, 'executeScript', args);\n\n          return {\n            value\n          };\n        },\n\n        async executeAsyncScript(fn, args) {\n          const value = await this.executeFn(fn, 'executeAsyncScript', args);\n\n          return {\n            value\n          };\n        },\n\n        ///////////////////////////////////////////////////////////\n        // Cookies\n        ///////////////////////////////////////////////////////////\n        async addCookie(cookie) {\n          await this.driver.manage().addCookie(cookie);\n\n          return null;\n        },\n\n        async deleteCookie(cookieName) {\n          await this.driver.manage().deleteCookie(cookieName);\n\n          return null;\n        },\n\n        async deleteAllCookies() {\n          await this.driver.manage().deleteAllCookies();\n\n          return null;\n        },\n\n        getCookies() {\n          return this.driver.manage().getCookies();\n        },\n\n        async getCookie(name) {\n          try {\n            const result = await this.driver.manage().getCookie(name);\n\n            return {\n              value: result\n            };\n          } catch (err) {\n            if (err.name === 'NoSuchCookieError') {\n              return null;\n            }\n\n            throw err;\n          }\n        },\n\n        ///////////////////////////////////////////////////////////\n        // User Actions\n        ///////////////////////////////////////////////////////////\n        async doubleClick(webElement) {\n          if (webElement) {\n            webElement = this.getWebElement(webElement);\n          }\n          await this.driver.actions({async: true}).doubleClick(webElement).perform();\n\n          return null;\n        },\n\n        /**\n         * @deprecated\n         */\n        mouseButtonClick(buttonIndex) {\n          return {\n            method: 'POST',\n            path: '/click',\n            data: {\n              button: buttonIndex\n            }\n          };\n        },\n\n        mouseButtonUp(buttonIndex) {\n          return {\n            method: 'POST',\n            path: '/buttonup',\n            data: {\n              button: buttonIndex\n            }\n          };\n        },\n\n        mouseButtonDown(buttonIndex) {\n          return {\n            method: 'POST',\n            path: '/buttondown',\n            data: {\n              button: buttonIndex\n            }\n          };\n        },\n\n\n        /**\n         * @param {string|WebElement|null} origin\n         * @param {number} x\n         * @param {number} y\n         * @param {object} [options]\n         * @param {number} [duration]\n         */\n\n        async moveTo(origin, x, y, duration, options = {}) {\n          switch (origin) {\n            case Origin.POINTER:\n              break;\n            case Origin.VIEWPORT:\n              break;\n\n            default:\n              origin = this.getWebElement(origin);\n          }\n\n          const moveOptions = {origin, x, y};\n          if (typeof duration != 'undefined') {\n            moveOptions.duration = duration;\n          }\n\n          await this.driver.actions(options).move(moveOptions).perform();\n\n          return null;\n        },\n\n        async dragElement(source, destination) {\n          source = this.getWebElement(source);\n\n          //destination could be webElementId or {x,y} offset\n          if (typeof destination === 'string') {\n            destination = this.getWebElement(destination);\n          }\n\n          await this.driver.actions({async: true}).dragAndDrop(source, destination).perform();\n\n          return null;\n        },\n\n        async contextClick(webElementOrId) {\n          const element = this.getWebElement(webElementOrId);\n          await this.driver.actions({async: true}).contextClick(element).perform();\n\n          return null;\n        },\n\n        async pressAndHold(webElementOrId) {\n\n          const element = this.getWebElement(webElementOrId);\n          await this.driver.actions({async: true}).move({origin: element}).press().perform();\n\n          return null;\n        },\n\n        async release(webElementOrId) {\n          await this.driver.actions({async: true}).release().perform();\n\n          return null;\n        },\n        ///////////////////////////////////////////////////////////\n        // User Prompts\n        ///////////////////////////////////////////////////////////\n        async acceptAlert() {\n          await this.driver.switchTo().alert().accept();\n\n          return null;\n        },\n\n        async dismissAlert() {\n          await this.driver.switchTo().alert().dismiss();\n\n          return null;\n        },\n\n        getAlertText() {\n          return this.driver.switchTo().alert().getText();\n        },\n\n        async setAlertText(keys) {\n          await this.driver.switchTo().alert().sendKeys(keys);\n\n          return null;\n        },\n\n        ///////////////////////////////////////////////////////////\n        // Screen\n        ///////////////////////////////////////////////////////////\n        async getScreenshot(logBase64Data) {\n          const data = await this.driver.takeScreenshot();\n\n          return {\n            value: data,\n            status: 0,\n            suppressBase64Data: !logBase64Data\n          };\n        },\n\n        getScreenOrientation() {\n          return '/orientation';\n        },\n\n        setScreenOrientation(orientation) {\n          return {\n            method: 'POST',\n            path: '/orientation',\n            data: {\n              orientation\n            }\n          };\n        },\n\n        ///////////////////////////////////////////////////////////\n        // Appium\n        ///////////////////////////////////////////////////////////\n\n        getAvailableContexts() {\n          return '/contexts';\n        },\n\n        getCurrentContext() {\n          return '/context';\n        },\n\n        setCurrentContext(context) {\n          return {\n            method: 'POST',\n            path: '/context',\n            data: {\n              name: context\n            }\n          };\n        },\n\n        startActivity(opts) {\n          return {\n            method: 'POST',\n            path: '/appium/device/start_activity',\n            data: opts\n          };\n        },\n\n        getCurrentActivity() {\n          return '/appium/device/current_activity';\n        },\n\n        getCurrentPackage() {\n          return '/appium/device/current_package';\n        },\n\n        getDeviceGeolocation() {\n          return '/location';\n        },\n\n        setDeviceGeolocation(location) {\n          return {\n            method: 'POST',\n            path: '/location',\n            data: {location}\n          };\n        },\n\n        pressDeviceKeyCode(opts) {\n          return {\n            method: 'POST',\n            path: '/appium/device/press_keycode',\n            data: opts\n          };\n        },\n\n        longPressDeviceKeyCode(opts) {\n          return {\n            method: 'POST',\n            path: '/appium/device/long_press_keycode',\n            data: opts\n          };\n        },\n\n        hideDeviceKeyboard(opts) {\n          return {\n            method: 'POST',\n            path: '/appium/device/hide_keyboard',\n            data: opts\n          };\n        },\n\n        isDeviceKeyboardShown() {\n          return '/appium/device/is_keyboard_shown';\n        },\n\n        resetApp() {\n          return {\n            method: 'POST',\n            path: '/appium/app/reset'\n          };\n        },\n\n        ///////////////////////////////////////////////////////////////////////////\n        // Selenium Webdriver\n        ///////////////////////////////////////////////////////////////////////////\n        async wait(conditionFn, timeMs, message, retryInterval) {\n          const driver = new WebDriver(Promise.resolve());\n          await driver.wait(conditionFn instanceof Condition ? conditionFn : conditionFn(), timeMs, message, retryInterval);\n\n          return {\n            value: null\n          };\n        },\n\n\n        async setNetworkConditions(spec) {\n          await this.driver.setNetworkConditions(spec);\n\n          return {\n            value: null\n          };\n        },\n\n        waitUntilElementsLocated({condition, timeout, retryInterval}) {\n          return this.driver.wait(until.elementsLocated(condition), timeout, null, retryInterval);\n        },\n\n        ///////////////////////////////////////////////////////////////////////////\n        // BiDi apis\n        ///////////////////////////////////////////////////////////////////////////\n\n        async registerAuth(username, password) {\n          const cdpConnection = await cdp.getConnection(this.driver, true);\n          await this.driver.register(username, password, cdpConnection);\n\n          return {\n            value: null\n          };\n        },\n\n        async startLogsCapture(userCallback) {\n          const cdpConnection = await cdp.getConnection(this.driver);\n          await this.driver.onLogEvent(cdpConnection, userCallback);\n\n          return {\n            value: null\n          };\n        },\n\n        async catchJsExceptions(userCallback) {\n          const cdpConnection = await cdp.getConnection(this.driver);\n          await this.driver.onLogException(cdpConnection, userCallback);\n\n          return {\n            value: null\n          };\n        },\n\n        ///////////////////////////////////////////////////////////////////////////\n        // CDP commands\n        ///////////////////////////////////////////////////////////////////////////\n\n        async setGeolocation(coordinates) {\n          const cdpConnection = await cdp.getConnection(this.driver);\n\n          await cdpConnection.execute(\n            'Emulation.setGeolocationOverride',\n            coordinates\n          );\n\n          return {\n            value: null\n          };\n        },\n\n        async clearGeolocation() {\n          const cdpConnection = await cdp.getConnection(this.driver);\n\n          await cdpConnection.execute(\n            'Emulation.clearGeolocationOverride',\n            {}\n          );\n\n          return {\n            value: null\n          };\n        },\n\n        async setDeviceMetrics(metrics) {\n          const cdpConnection = await cdp.getConnection(this.driver);\n\n          await cdpConnection.execute(\n            'Emulation.setDeviceMetricsOverride',\n            metrics\n          );\n\n          return {\n            value: null\n          };\n        },\n\n        async interceptNetworkCalls(userCallback) {\n          const cdpConnection = await cdp.getConnection(this.driver);\n\n          cdpConnection._wsConnection.on('message', (message) => {\n            const params = JSON.parse(message);\n            if (params.method === 'Network.requestWillBeSent') {\n              const requestParams = params['params'];\n\n              userCallback(requestParams);\n            }\n          });\n\n          await cdpConnection.execute(\n            'Network.enable',\n            {}\n          );\n\n          return {\n            value: null\n          };\n        },\n\n        async mockNetworkResponse(urlToIntercept, response) {\n          const cdpConnection = await cdp.getConnection(this.driver);\n\n          const {status = 200, headers: headersObject, body: bodyPlain = ''} = response;\n          const headers = [];\n          if (headersObject) {\n            for (const [name, value] of Object.entries(headersObject)) {\n              headers.push({name, value});\n            }\n          }\n          // Convert body to base64\n          const bodyBase64 = Buffer.from(bodyPlain, 'utf-8').toString('base64');\n\n          cdp.addNetworkMock(urlToIntercept, {status, headers, body: bodyBase64});\n\n          // Add event listener only the first time.\n          if (Object.keys(cdp.networkMocks).length === 1) {\n            cdpConnection._wsConnection.on('message', (message) => {\n              const params = JSON.parse(message);\n              if (params.method === 'Fetch.requestPaused') {\n                const requestPausedParams = params['params'];\n                const requestUrl = requestPausedParams.request.url;\n\n                const networkMocks = cdp.networkMocks;\n                if (Object.keys(networkMocks).includes(requestUrl)) {\n                  const mockResponse = networkMocks[requestUrl];\n                  cdpConnection.execute('Fetch.fulfillRequest', {\n                    requestId: requestPausedParams['requestId'],\n                    responseCode: mockResponse.status,\n                    responseHeaders: mockResponse.headers,\n                    body: mockResponse.body\n                  });\n                } else {\n                  cdpConnection.execute('Fetch.continueRequest', {\n                    requestId: requestPausedParams['requestId']\n                  });\n                }\n              }\n            });\n          }\n\n          await cdpConnection.execute(\n            'Fetch.enable',\n            {}\n          );\n          await cdpConnection.execute(\n            'Network.setCacheDisabled',\n            {cacheDisabled: true}\n          );\n\n          return {\n            value: null\n          };\n        },\n\n        async takeHeapSnapshot(heapSnapshotLocation) {\n          const cdpConnection = await cdp.getConnection(this.driver);\n\n          const chunks = [];\n          cdpConnection._wsConnection.on('message', (message) => {\n            const params = JSON.parse(message);\n            if (params.method === 'HeapProfiler.addHeapSnapshotChunk') {\n              const chunk = params['params']['chunk'];\n\n              chunks.push(chunk);\n            }\n          });\n\n          await cdpConnection.execute(\n            'HeapProfiler.enable',\n            {}\n          );\n\n          await cdpConnection.execute(\n            'HeapProfiler.takeHeapSnapshot',\n            {}\n          );\n\n          let prevChunks = [];\n\n          return new Promise((resolve) => {\n            const intervalId = setInterval(() => {\n              if (prevChunks.length !== 0 && prevChunks.length === chunks.length) {\n                resolveAndClearInterval();\n              }\n              prevChunks = [...chunks];\n            }, 100);\n\n            const resolveAndClearInterval = () => {\n              clearInterval(intervalId);\n\n              const heapSnapshot = chunks.join('');\n              if (heapSnapshotLocation) {\n                fs.writeFileSync(heapSnapshotLocation, heapSnapshot);\n              }\n\n              resolve({value: heapSnapshot});\n            };\n          });\n        },\n\n        async enablePerformanceMetrics(enable) {\n          // Disable the metrics once even before enabling it.\n          await this.driver.sendAndGetDevToolsCommand('Performance.disable');\n\n          if (enable) {\n            await this.driver.sendAndGetDevToolsCommand('Performance.enable');\n          }\n\n          return {\n            value: null\n          };\n        },\n\n        async getPerformanceMetrics() {\n          const {metrics: metricsReturned} = await this.driver.sendAndGetDevToolsCommand('Performance.getMetrics');\n\n          const metrics = {};\n          for (const metric of metricsReturned) {\n            metrics[metric.name] = metric.value;\n          }\n\n          return {\n            value: metrics\n          };\n        }\n\n      }\n    };\n  }\n};\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/options.js",
    "content": "const {Capabilities, Browser} = require('selenium-webdriver');\nconst Utils = require('../../utils');\n\nmodule.exports = class SeleniumCapabilities {\n  get initialCapabilities() {\n    return this.__capabilities;\n  }\n\n  get isChrome() {\n    return this.initialCapabilities.getBrowserName() === Browser.CHROME;\n  }\n\n  get isSafari() {\n    return this.initialCapabilities.getBrowserName() === Browser.SAFARI;\n  }\n\n  get isEdge() {\n    return this.initialCapabilities.getBrowserName() === Browser.EDGE;\n  }\n\n  get isFirefox() {\n    return this.initialCapabilities.getBrowserName() === Browser.FIREFOX;\n  }\n\n  constructor({settings, browserName}) {\n    this.settings = settings;\n\n    this.createDesired();\n    this.__capabilities = this.createInitialCapabilities();\n\n    if (browserName) {\n      this.initialCapabilities.setBrowserName(browserName);\n    }\n  }\n\n  createDesired() {\n    this.desiredCapabilities = this.settings.capabilities || this.settings.desiredCapabilities;\n\n    // flatten alwaysMatch param from desired Capabilities\n    if (this.desiredCapabilities.alwaysMatch) {\n      Object.assign(this.desiredCapabilities, this.desiredCapabilities.alwaysMatch);\n      delete this.desiredCapabilities['alwaysMatch'];\n    }\n\n    if (typeof this.desiredCapabilities == 'function') {\n      this.desiredCapabilities = this.desiredCapabilities.call(this.settings);\n    }\n\n    return this.desiredCapabilities;\n  }\n\n  /**\n   * Create an initial capabilities instance based on either the capabilities or desiredCapabilities\n   *  setting from the nightwatch config\n   *\n   * @returns {Capabilities}\n   */\n  createInitialCapabilities() {\n    if (this.desiredCapabilities instanceof Capabilities) {\n      return this.desiredCapabilities;\n    }\n\n    return new Capabilities(this.desiredCapabilities);\n  }\n\n  alreadyDefinedAs(OptionsClass) {\n    return this.desiredCapabilities instanceof OptionsClass;\n  }\n\n  create(argv = {}) {\n    this.argv = argv;\n    let options;\n\n    switch (this.initialCapabilities.getBrowserName()) {\n      case Browser.CHROME:\n        options = this.createChromeOptions();\n        break;\n\n      case Browser.FIREFOX:\n        options = this.createFirefoxOptions();\n        break;\n\n      case Browser.SAFARI:\n        options = this.createSafariOptions();\n        break;\n\n      case Browser.EDGE:\n        options = this.createEdgeOptions();\n        break;\n\n      case Browser.OPERA:\n        // TODO: implement\n        break;\n\n      case Browser.INTERNET_EXPLORER:\n        options = this.createIeOptions();\n        break;\n    }\n\n    this\n      .updateWebdriverPath()\n      .addHeadlessOption({options})\n      .addDevtoolsOption({options})\n      .addWindowSizeOption({options})\n      .addProxyOption({options});\n\n    return options;\n  }\n\n  /**\n   * @return {chrome.Options}\n   */\n  createChromeOptions() {\n    const {Options: ChromeOptions} = require('selenium-webdriver/chrome');\n\n    if (this.alreadyDefinedAs(ChromeOptions)) {\n      return this.desiredCapabilities;\n    }\n\n    // Backward compatibility for 'chromeOptions'\n    if (Utils.isObject(this.desiredCapabilities.chromeOptions)) {\n      this.desiredCapabilities['goog:chromeOptions'] = Object.assign(\n        this.desiredCapabilities.chromeOptions,\n        this.desiredCapabilities['goog:chromeOptions']\n      );\n    }\n\n    const {webdriver} = this.settings;\n    const options = new ChromeOptions(this.desiredCapabilities);\n\n    if (webdriver.chrome_binary || this.settings.chrome_binary) {\n      options.setChromeBinaryPath(webdriver.chrome_binary || this.settings.chrome_binary);\n    }\n\n    if (webdriver.chrome_log_file || this.settings.chrome_log_file) {\n      options.setChromeLogFile(webdriver.chrome_log_file || this.settings.chrome_log_file);\n    }\n\n    if (webdriver.android_chrome) {\n      options.androidChrome();\n    }\n\n    return options;\n  }\n\n  createIeOptions() {\n    const {Options: IeOptions} = require('selenium-webdriver/ie');\n\n    if (this.alreadyDefinedAs(IeOptions)){\n      return this.desiredCapabilities;\n    }\n\n    const {webdriver} = this.settings;\n    const options = new IeOptions(this.desiredCapabilities);\n\n    if (webdriver.log_path || this.settings.log_path) {\n      options.setLogFile(webdriver.log_path || this.settings.log_path);\n    }\n\n    if (webdriver.host || this.settings.host) {\n      options.setHost(webdriver.host || this.settings.host);\n    }\n\n    return options;\n  }\n\n  createEdgeOptions() {\n    const {Options: EdgeOptions} = require('selenium-webdriver/edge');\n\n    if (this.alreadyDefinedAs(EdgeOptions)) {\n      return this.desiredCapabilities;\n    }\n\n    const {webdriver} = this.settings;\n    const options = new EdgeOptions(this.desiredCapabilities);\n\n    if (webdriver.edge_binary || this.settings.edge_binary) {\n      options.setEdgeChromiumBinaryPath(webdriver.edge_binary || this.settings.edge_binary);\n    }\n\n    if (webdriver.edge_log_file || this.settings.edge_log_file) {\n      options.setBrowserLogFile(webdriver.edge_log_file || this.settings.edge_log_file);\n    }\n\n    if (webdriver.android_package) {\n      options.androidPackage(webdriver.android_package);\n    }\n\n    return options;\n  }\n\n  /**\n   * @return {firefox.Options}\n   */\n  createFirefoxOptions() {\n    const {Options: FirefoxOptions} = require('selenium-webdriver/firefox');\n\n    if (this.alreadyDefinedAs(FirefoxOptions)) {\n      return this.desiredCapabilities;\n    }\n\n    const {webdriver} = this.settings;\n    const options = new FirefoxOptions(this.desiredCapabilities);\n\n    if (webdriver.firefox_binary || this.settings.firefox_binary) {\n      options.setBinary(webdriver.firefox_binary || this.settings.firefox_binary);\n    }\n\n    if (webdriver.firefox_profile || this.settings.firefox_profile) {\n      options.setProfile(webdriver.firefox_profile || this.settings.firefox_profile);\n    }\n\n    return options;\n  }\n\n  createSafariOptions() {\n    const {Options: SafariOptions} = require('selenium-webdriver/safari');\n\n    if (this.alreadyDefinedAs(SafariOptions)) {\n      return this.desiredCapabilities;\n    }\n\n    const options = new SafariOptions(this.desiredCapabilities);\n\n    return options;\n  }\n\n  usingSeleniumServer() {\n    return this.settings.selenium && this.settings.selenium.start_process;\n  }\n\n  shouldSetupWebdriver() {\n    return this.settings.webdriver.start_process && !this.settings.webdriver.server_path;\n  }\n\n  getChromedriverPath() {\n    try {\n      return require('chromedriver').path;\n    } catch (err) {\n      return '';\n    }\n  }\n\n  getGeckodriverPath() {\n    try {\n      return require('geckodriver').path;\n    } catch (err) {\n      return '';\n    }\n  }\n\n  getAppiumPath() {\n    return require.resolve('appium');\n  }\n\n  updateWebdriverPath() {\n    if (this.shouldSetupWebdriver()) {\n      try {\n        if (this.usingSeleniumServer()) {\n          if (this.settings.selenium.use_appium) {\n            this.settings.selenium.server_path = this.settings.webdriver.server_path = this.getAppiumPath();\n\n            return this;\n          }\n\n          this.settings.selenium.server_path = this.settings.webdriver.server_path = require('@nightwatch/selenium-server').path;\n          this.settings.selenium.cli_args = this.settings.selenium.cli_args || {};\n\n          const chromeDriver = this.getChromedriverPath();\n          if (chromeDriver) {\n            this.settings.selenium.cli_args['webdriver.chrome.driver'] = chromeDriver;\n          }\n\n          const geckoDriver = this.getGeckodriverPath();\n          if (geckoDriver) {\n            this.settings.selenium.cli_args['webdriver.gecko.driver'] = geckoDriver;\n          }\n\n          return this;\n        }\n\n        switch (this.initialCapabilities.getBrowserName()) {\n          case Browser.CHROME:\n            this.settings.webdriver.server_path = this.getChromedriverPath();\n            break;\n\n          case Browser.FIREFOX:\n            this.settings.webdriver.server_path = this.getGeckodriverPath();\n            break;\n\n          case Browser.SAFARI:\n            this.settings.webdriver.server_path = '/usr/bin/safaridriver';\n            break;\n        }\n      } catch (err) {\n        this.settings.webdriver.server_path = '';\n      }\n    }\n\n    return this;\n  }\n\n  hasDevtoolsFlag(options) {\n    return this.argv.devtools && (options instanceof Capabilities);\n  }\n\n  addDevtoolsOption({options}) {\n    if (!this.hasDevtoolsFlag(options)) {\n      return this;\n    }\n\n    if (this.isChrome) {\n      const {args = []} = options.get('goog:chromeOptions');\n      const newArg = 'auto-open-devtools-for-tabs';\n\n      if (!(args.includes(newArg) || args.includes(`--${newArg}`))) {\n        options.addArguments(newArg);\n      }\n    } else if (this.isSafari) {\n      options.map_.set('safari:automaticInspection', true);\n    } else if (this.isEdge) {\n      const {args = []} = options.get('ms:edgeOptions');\n      const newArg = 'auto-open-devtools-for-tabs';\n\n      if (!(args.includes(newArg) || args.includes(`--${newArg}`))) {\n        options.addArguments(newArg);\n      }\n    } else if (this.isFirefox) {\n      // TODO: implement when available in Firefox\n    }\n\n    return this;\n  }\n\n  addHeadlessOption({options}) {\n    if (this.argv.headless && (options instanceof Capabilities) && options.addArguments) {\n      // For other Chromium-based browsers, `options` wouldn't be an instance of Capabilities\n      // because it is never made so above (not officially supported by Selenium).\n      if (this.isChrome || this.isEdge) {\n        options.addArguments('headless=new');\n      } else if (this.isFirefox) {\n        options.addArguments('-headless');\n      }\n    }\n\n    return this;\n  }\n\n  addWindowSizeOption({options}) {\n    if (this.settings.window_size && (options instanceof Capabilities) && options.windowSize) {\n      options.windowSize(this.settings.window_size);\n    }\n\n    return this;\n  }\n\n  addProxyOption({options}) {\n    if (this.initialCapabilities.getProxy() && (options instanceof Capabilities) && options.setProxy) {\n      const proxy = require('selenium-webdriver/proxy');\n      options.setProxy(proxy.manual(this.initialCapabilities.getProxy()));\n    }\n  }\n};\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/safari.js",
    "content": "const {WebDriver} = require('selenium-webdriver');\nconst http = require('selenium-webdriver/http');\nconst SeleniumWebdriver = require('./');\n\nmodule.exports = class SafariDriverTransport extends SeleniumWebdriver {\n  get ServiceBuilder() {\n    return require('./service-builders/safari.js');\n  }\n\n  get defaultServerUrl() {\n    return 'http://127.0.0.1:4444/';\n  }\n\n  createDriver({options}) {\n    let service;\n    let serverUrl;\n\n    if (this.driverService) {\n      service = this.driverService.service.build();\n    }\n\n    serverUrl = this.getServerUrl();\n\n    return SafariDriver.createSession(options, service, serverUrl);\n  }\n};\n\n// Licensed to the Software Freedom Conservancy (SFC) under one\n// or more contributor license agreements.  See the NOTICE file\n// distributed with this work for additional information\n// regarding copyright ownership.  The SFC licenses this file\n// to you under the Apache License, Version 2.0 (the\n// \"License\"); you may not use this file except in compliance\n// with the License.  You may obtain a copy of the License at\n//\n//   http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing,\n// software distributed under the License is distributed on an\n// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n// KIND, either express or implied.  See the License for the\n// specific language governing permissions and limitations\n// under the License.\n\n// Built-in SafariDriver class doesn't support passing the service object\nclass SafariDriver extends WebDriver {\n  static createSession(options, service, serverUrl) {\n    let client;\n\n    if (service) {\n      client = service.start().then(url => new http.HttpClient(url));\n    } else {\n      client = Promise.resolve(new http.HttpClient(serverUrl));\n    }\n\n    const executor = new http.Executor(client);\n\n    return super.createSession(executor, options, () => {\n      if (service) {\n        service.kill();\n      }\n    });\n  }\n\n  /**\n   * This function is a no-op as file detectors are not supported by this\n   * implementation.\n   * @override\n   */\n  setFileDetector() {}\n}\n\n\n\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/selenium.js",
    "content": "const DefaultSeleniumDriver = require('./');\nconst SeleniumServiceBuilder = require('./service-builders/selenium.js');\n\nmodule.exports = class SeleniumServer extends DefaultSeleniumDriver {\n  /**\n   * Used when running in parallel with start_process=true\n   */\n  static createService(settings) {\n    const Options = require('./options.js');\n    const opts = new Options({settings});\n    opts.updateWebdriverPath();\n\n    const seleniumService = new SeleniumServiceBuilder(settings);\n\n    const outputFile = settings.webdriver.log_file_name || '';\n    seleniumService.setOutputFile(outputFile);\n\n    return seleniumService;\n  }\n\n  get defaultBrowser() {\n    return 'firefox';\n  }\n\n  get ServiceBuilder() {\n    return SeleniumServiceBuilder;\n  }\n\n  get defaultServerUrl() {\n    return 'http://127.0.0.1:4444';\n  }\n\n  get defaultPathPrefix() {\n    return '/wd/hub';\n  }\n\n  constructor(nightwatchInstance, browserName) {\n    if (nightwatchInstance.settings.selenium && nightwatchInstance.settings.selenium['[_started]']) {\n      nightwatchInstance.settings.selenium.start_process = false;\n      nightwatchInstance.settings.webdriver.start_process = false;\n    }\n\n    super(nightwatchInstance, {isSelenium: true, browserName});\n  }\n\n  async closeDriver() {}\n\n  async sessionFinished(reason) {\n    this.emit('session:finished', reason);\n\n    // TODO: refactor this, selenium server management has moved to runner/cli\n    if (this.driverService) {\n      const {service} = this.driverService;\n      if (service && service.kill) {\n        // Give the selenium server some time to close down its browser drivers\n        return new Promise((resolve, reject) => {\n          setTimeout(() => {\n            service.kill()\n              .catch(err => reject(err))\n              .then(() => this.driverService.stop())\n              .then(() => resolve());\n          }, 100);\n        });\n      }\n    }\n  }\n\n  setBuilderOptions({builder, options}) {\n    const serverUrl = this.getServerUrl();\n\n    builder\n      .usingServer(serverUrl)\n      .withCapabilities(this.initialCapabilities);\n\n    return super.setBuilderOptions({builder, options});\n  }\n};\n\n\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/service-builders/appium.js",
    "content": "const {SeleniumServer, DriverService} = require('selenium-webdriver/remote');\nconst {getFreePort} = require('../../../utils');\nconst BaseService = require('./base-service.js');\n\nclass AppiumService extends DriverService {\n  constructor(server_path, opt_options) {\n    const options = opt_options || {};\n    const {args, default_path_prefix} = options;\n\n    const port = options.port;\n    if (port !== AppiumServiceBuilder.defaultPort && !args.includes('--port')) {\n      args.unshift('--port', port);\n    }\n\n    let cmd = 'node';\n    if (server_path.startsWith('appium')) {\n      cmd = server_path;\n    } else {\n      args.unshift(server_path);\n    }\n\n    super(cmd, {\n      loopback: options.loopback,\n      port,\n      args,\n      path: default_path_prefix,\n      env: options.env,\n      stdio: options.stdio\n    });\n  }\n}\n\nclass AppiumServiceBuilder extends BaseService {\n  static get serviceName() {\n    return 'Appium Server';\n  }\n\n  static get defaultPort() {\n    return 4723;\n  }\n\n  get npmPackageName() {\n    return 'appium';\n  }\n\n  get outputFile() {\n    return this._outputFile + '_appium-server.log';\n  }\n\n  get defaultPort() {\n    return AppiumServiceBuilder.defaultPort;\n  }\n\n  get serviceName() {\n    return 'Appium Server';\n  }\n\n  get downloadMessage() {\n    return 'install Appium globally with \"npm i -g appium\" command, \\n and set ' +\n      '\"selenium.server_path\" config option to \"appium\".';\n  }\n\n  /**\n   * @param {Capabilities} opts\n   * @returns {Promise<void>}\n   */\n  async createService(opts = {}) {\n    const {port} = this;\n    const options = new SeleniumServer.Options();\n    options.port = port || await getFreePort();\n    const {server_path, default_path_prefix = '/wd/hub'} = this.settings.webdriver;\n\n    const introMsg = `Starting Appium Server on port ${options.port}...`;\n\n    if (opts.showSpinner) {\n      opts.showSpinner(`${introMsg}\\n\\n`);\n    } else {\n      // eslint-disable-next-line\n      console.info(introMsg);\n    }\n\n    // TODO: read the log_path and add it to cliArgs\n    // above TODO is copied from ./selenium.js\n    options.args = this.cliArgs;\n    options.default_path_prefix = default_path_prefix;\n\n    if (this.hasSinkSupport() && this.needsSinkProcess()) {\n      this.createSinkProcess();\n      options.stdio = ['pipe', this.process.stdin, this.process.stdin];\n    }\n\n    this.service = new AppiumService(server_path, options);\n\n    return this.service.start();\n  }\n}\n\nmodule.exports = AppiumServiceBuilder;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/service-builders/base-service.js",
    "content": "const path = require('path');\nconst child_process = require('child_process');\nconst fs = require('fs');\nconst Concurrency = require('../../../runner/concurrency');\nconst {Logger, createFolder} = require('../../../utils');\n\nclass BaseService {\n  get outputFile() {\n    return this._outputFile + '_webdriver.log';\n  }\n\n  get serviceName() {\n    return 'WebDriver';\n  }\n\n  get serviceDownloadUrl() {\n    return '';\n  }\n\n  get requiresDriverBinary() {\n    return true;\n  }\n\n  static get DEFAULT_HOST() {\n    return 'localhost';\n  }\n\n  get npmPackageName() {\n    return null;\n  }\n\n  get downloadMessage() {\n    return `download it from ${this.serviceDownloadUrl}, \\nextract the archive and set ` +\n      '\"webdriver.server_path\" config option to point to the binary file.\\n';\n  }\n\n  get errorMessages() {\n    let binaryMissing = `${this.serviceName} cannot be found in the current project.`;\n\n    if (this.npmPackageName) {\n      binaryMissing += '\\n\\n ' + Logger.colors.yellow.bold(`You can either install ${this.npmPackageName} from NPM with: \\n\\n    npm install ${this.npmPackageName} --save-dev\\n\\n`) + ' or ';\n    } else {\n      binaryMissing += '\\n\\n Please ';\n    }\n\n    binaryMissing += this.downloadMessage;\n\n    return {\n      binaryMissing\n    };\n  }\n\n  get errorOutput() {\n    const errorOut = this.error_out.split('\\n');\n\n    return errorOut.reduce(function(prev, message) {\n      if (prev.indexOf(message) < 0) {\n        prev.push(message);\n      }\n\n      return prev;\n    }, []).join('\\n ');\n  }\n\n  get defaultPort() {\n    return undefined;\n  }\n\n  constructor(settings) {\n    this.settings = settings;\n    this.process = null;\n    this.output = '';\n    this.error_out = '';\n    this.cliArgs = [];\n    this.processExited = false;\n\n    this.hostname = this.settings.webdriver.host || BaseService.DEFAULT_HOST;\n    this.port = this.settings.webdriver.port;\n\n    if (!this.settings.webdriver.server_path && this.requiresDriverBinary) {\n      throw this.getStartupErrorMessage(this.errorMessages.binaryMissing);\n    }\n\n    this.exitListener = function exitListenerSink() {\n      return this.stop();\n    }.bind(this);\n\n    process.on('exit', this.exitListener);\n\n    process.on('SIGINT', () => {\n      this.stop().then(_ => {\n        process.exit(0);\n      });\n    });\n  }\n\n  setCliArgs(args) {\n    const {cli_args} = this.settings.webdriver;\n    const cliArgs = Array.isArray(args) ? args : cli_args;\n\n    if (Array.isArray(cliArgs)) {\n      cliArgs.forEach(item => {\n        if (typeof item == 'string') {\n          this.cliArgs.push(item);\n        }\n      });\n    }\n  }\n\n  createSinkProcess() {\n    const exitHandler = this.onExit.bind(this);\n\n    this.process = child_process.spawn('cat', [], {\n      env: process.env,\n      stdio: ['pipe', 'pipe', 'pipe']\n    });\n    this.process.unref();\n\n    this.process.stdout.on('data', this.onStdout.bind(this));\n    this.process.stderr.on('data', this.onStderr.bind(this));\n\n    this.process.on('error', this.onError.bind(this));\n    this.process.on('exit', exitHandler);\n    this.process.on('close', this.onClose.bind(this));\n\n    if (this.service) {\n      this.service.setStdio(['pipe', this.process.stdin, this.process.stdin]);\n    }\n  }\n\n  createErrorMessage(code) {\n    return `${this.serviceName} process exited with code: ${code}`;\n  }\n\n  /**\n   * @override\n   * @param code\n   */\n  onExit(code) {\n    if (this.processExited) {\n      return this;\n    }\n\n    if (code === null || code === undefined) {\n      code = 0;\n    }\n\n    this.processExited = true;\n\n    if (code > 0) {\n      const err = this.createError(null, code);\n      err.detailedErr = this.error_out || this.output;\n    }\n  }\n\n  /**\n   * @override\n   * @param err\n   */\n  onError(err) {\n    let errMessage;\n    if (err.code === 'ENOENT') {\n      errMessage = `\\nAn error occurred while trying to start ${this.serviceName}: cannot resolve path: \"${err.path}\".`;\n    }\n\n    Logger.error(errMessage || err);\n\n    if (err.code === 'ENOENT') {\n      // eslint-disable-next-line no-console\n      console.warn('Please check that the \"webdriver.server_path\" config property is set correctly.\\n');\n    }\n\n    process.nextTick(() => this.stop());\n  }\n\n  onClose() {\n    Logger.info(`${this.serviceName} process closed.`);\n  }\n\n  createError(message, code = 1) {\n    if (!message && code) {\n      message = this.createErrorMessage(code);\n    }\n\n    const err = new Error(message);\n    err.code = code;\n    err.errorOut = this.errorOutput;\n\n    return err;\n  }\n\n  getStartupErrorMessage(message) {\n    const err = this.createError(message);\n\n    const parts = message.split('\\n');\n    const messageLine = parts.shift();\n    const startUpError = new Error(messageLine);\n\n    if (parts.length > 0) {\n      startUpError.detailedErr = parts.join('\\n');\n    }\n    if (err.code) {\n      startUpError.code = err.code;\n    }\n    startUpError.showTrace = false;\n\n    return startUpError;\n  }\n\n  onStdout(data) {\n    this.output += data.toString();\n  }\n\n  onStderr(data) {\n    this.output += data.toString();\n    this.error_out += data.toString();\n  }\n\n  needsSinkProcess() {\n    return !Concurrency.isWorker();\n  }\n\n  hasSinkSupport() {\n    return process.platform !== 'win32' || process.env._ && process.env._.startsWith('/usr/');\n  }\n\n  /**\n   * @param {Capabilities} options\n   * @returns {Promise<void>}\n   */\n  async createService(options) {\n    const {default_path_prefix, server_path} = this.settings.webdriver;\n    const {hostname, port} = this;\n    let serverPathLog = '';\n\n\n    this.seleniumLogPath = this.settings.webdriver.log_path;\n\n    if (server_path) {\n      serverPathLog = ` with server_path=${server_path}`;\n    }\n\n    Logger.info(`Starting ${this.serviceName}${serverPathLog}...`);\n\n    if (this.hasSinkSupport() && this.needsSinkProcess()) {\n      await this.createSinkProcess();\n    } else {\n      this.settings.webdriver.log_path = false;\n    }\n\n    if (port) {\n      this.service.setPort(port);\n    }\n\n    if (hostname) {\n      this.service.setHostname(hostname);\n    }\n\n    if (default_path_prefix) {\n      this.service.setPath(default_path_prefix);\n    }\n  }\n\n  async init(options = {}) {\n    this.processExited = false;\n    this.stopped = false;\n    this.startTime = new Date();\n\n    this.setCliArgs();\n\n    try {\n      await this.createService(options);\n    } catch (err) {\n      const {message} = err;\n      err.message = `Unable to create the ${this.serviceName} process: ${message}`;\n      err.detailedErr = '; verify if webdriver is configured correctly; using:\\n  ' + this.getSettingsFormatted() + '\\n';\n      err.showTrace = false;\n      err.sessionCreate = true;\n\n      return Promise.reject(err);\n    }\n  }\n\n  getSettingsFormatted() {\n    const {start_process, server_path, port, host, ssl, default_path_prefix, proxy, cli_args} = this.settings.webdriver;\n    const displaySettings = {\n      start_process, server_path, port, host, ssl, default_path_prefix, proxy, cli_args\n    };\n\n    return Logger.inspectObject(displaySettings);\n  }\n\n  async stop() {\n    if (this.exitListener) {\n      process.removeListener('exit', this.exitListener);\n    }\n\n    if (this.stopped) {\n      return;\n    }\n\n    await this.writeLogFile();\n    if (!this.process || this.process.killed) {\n      return;\n    }\n\n    try {\n      this.process.kill();\n    } catch (err) {\n      Logger.error(err);\n\n      return Promise.reject(err);\n    }\n  }\n\n  setOutputFile(fileName) {\n    this._outputFile = fileName;\n\n    return this;\n  }\n\n  getSeleniumLogPath() {\n    return path.resolve(this.seleniumLogPath || 'logs');\n  }\n\n  getLogPath() {\n    const {log_path = 'logs'} = this.settings.webdriver;\n    if (log_path === false) {\n      return null;\n    }\n\n    return path.resolve(log_path);\n  }\n\n  getSeleniumOutputFilePath() {\n    const {log_file_name} = this.settings.webdriver;\n    if (log_file_name) {\n      this._outputFile = log_file_name;\n    }\n\n    return path.join(this.getSeleniumLogPath(), this.outputFile);\n  }\n\n  getOutputFilePath() {\n    const logPath = this.getLogPath();\n    if (!logPath) {\n      return null;\n    }\n\n    const {log_file_name} = this.settings.webdriver;\n    if (log_file_name) {\n      this._outputFile = log_file_name;\n    }\n\n    return path.join(logPath, this.outputFile);\n  }\n\n  async writeLogFile() {\n    const logPath = this.getLogPath();\n    if (!logPath) {\n      return true;\n    }\n\n    const filePath = this.getOutputFilePath();\n    const folderPath = path.dirname(filePath);\n    await createFolder(folderPath);\n\n    return new Promise((resolve, reject) => {\n      fs.writeFile(filePath, this.output, (err) => {\n        if (err) {\n          Logger.error(`Cannot write log file to ${filePath}.`);\n          Logger.warn(err);\n          this.stopped = true;\n\n          return resolve();\n        }\n\n        Logger.info(`Wrote log file to: ${filePath}`);\n        this.stopped = true;\n        resolve();\n      });\n    });\n  }\n}\n\nmodule.exports = BaseService;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/service-builders/chrome.js",
    "content": "const chrome = require('selenium-webdriver/chrome');\nconst BaseService = require('./base-service.js');\n\nclass ChromeServiceBuilder extends BaseService {\n  static get serviceName() {\n    return 'ChromeDriver';\n  }\n\n  static get defaultPort() {\n    return 9515;\n  }\n\n  get npmPackageName() {\n    return 'chromedriver';\n  }\n\n  get outputFile() {\n    return this._outputFile + '_chromedriver.log';\n  }\n\n  get serviceName() {\n    return ChromeServiceBuilder.serviceName;\n  }\n\n  get serviceDownloadUrl() {\n    return 'https://sites.google.com/chromium.org/driver/downloads';\n  }\n\n  /**\n   * @param {Capabilities} options\n   * @returns {Promise<void>}\n   */\n  async createService(options) {\n    const {server_path} = this.settings.webdriver;\n    this.service = new chrome.ServiceBuilder(server_path);\n\n    let enableVerboseLogging = true;\n\n    if (Array.isArray(this.cliArgs) && this.cliArgs.length > 0) {\n      this.service.addArguments(...this.cliArgs);\n\n      for (const arg of this.cliArgs) {\n        if (arg === '--silent' || arg.startsWith('--log-level=')) {\n          enableVerboseLogging = false;\n          break;\n        }\n      }\n    }\n\n    if (enableVerboseLogging) {\n      this.service.enableVerboseLogging();\n    }\n\n    if (process.platform !== 'win32') {\n      this.service.enableChromeLogging();\n    }\n\n    return super.createService();\n  }\n\n\n  get requiresDriverBinary() {\n    return false;\n  }\n}\n\nmodule.exports = ChromeServiceBuilder;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/service-builders/edge.js",
    "content": "const edge = require('selenium-webdriver/edge');\nconst BaseService = require('./base-service.js');\n\nclass EdgeServiceBuilder extends BaseService {\n  static get serviceName() {\n    return 'EdgeDriver';\n  }\n\n  static get defaultPort() {\n    return 9514;\n  }\n\n  get requiresDriverBinary() {\n    return false;\n  }\n\n  get outputFile() {\n    return this._outputFile + '_msedgedriver.log';\n  }\n\n  get serviceName() {\n    return EdgeServiceBuilder.serviceName;\n  }\n\n  get serviceDownloadUrl() {\n    return 'https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/';\n  }\n\n  /**\n   * @param {Capabilities} options\n   * @returns {Promise<void>}\n   */\n  async createService(options) {\n    const {server_path} = this.settings.webdriver;\n    this.service = new edge.ServiceBuilder(server_path);\n\n    let enableVerboseLogging = true;\n\n    if (Array.isArray(this.cliArgs)) {\n      this.service.addArguments(...this.cliArgs);\n\n      for (const arg of this.cliArgs) {\n        if (arg === '--silent' || arg.startsWith('--log-level=')) {\n          enableVerboseLogging = false;\n          break;\n        }\n      }\n    }\n\n    if (enableVerboseLogging) {\n      this.service.enableVerboseLogging();\n    }\n\n    return super.createService();\n  }\n}\n\nmodule.exports = EdgeServiceBuilder;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/service-builders/firefox.js",
    "content": "const firefox = require('selenium-webdriver/firefox');\nconst BaseService = require('./base-service.js');\n\nclass FirefoxServiceBuilder extends BaseService {\n  static get serviceName() {\n    return 'GeckoDriver';\n  }\n\n  static get defaultPort() {\n    return 4444;\n  }\n\n  get npmPackageName() {\n    return 'geckodriver';\n  }\n\n  get outputFile() {\n    return this._outputFile + '_geckodriver.log';\n  }\n\n  get serviceName() {\n    return FirefoxServiceBuilder.serviceName;\n  }\n\n  get serviceDownloadUrl() {\n    return 'https://github.com/mozilla/geckodriver/releases';\n  }\n\n  /**\n   * @param {Capabilities} options\n   * @returns {Promise<void>}\n   */\n  async createService(options) {\n    const {server_path} = this.settings.webdriver;\n    this.service = new firefox.ServiceBuilder(server_path);\n\n    let enableVerboseLogging = true;\n\n    if (Array.isArray(this.cliArgs)) {\n      this.service.addArguments(...this.cliArgs);\n\n      if (this.cliArgs.includes('--log')) {\n        enableVerboseLogging = false;\n      }\n    }\n\n    if (enableVerboseLogging) {\n      this.service.enableVerboseLogging(true);\n    }\n\n    return super.createService();\n  }\n\n  get requiresDriverBinary() {\n    return false;\n  }\n}\n\nmodule.exports = FirefoxServiceBuilder;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/service-builders/safari.js",
    "content": "const {Capabilities} = require('selenium-webdriver');\nconst safari = require('selenium-webdriver/safari');\nconst BaseService = require('./base-service.js');\n\nconst OPTIONS_CAPABILITY_KEY = 'safari.options';\nconst TECHNOLOGY_PREVIEW_OPTIONS_KEY = 'technologyPreview';\nconst SAFARIDRIVER_TECHNOLOGY_PREVIEW_EXE = '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver';\n\nfunction useTechnologyPreview(o) {\n  if (o instanceof Capabilities) {\n    let options = o.get(OPTIONS_CAPABILITY_KEY);\n\n    return !!(options && options[TECHNOLOGY_PREVIEW_OPTIONS_KEY]);\n  }\n\n  if (o && typeof o === 'object') {\n    return !!o[TECHNOLOGY_PREVIEW_OPTIONS_KEY];\n  }\n\n  return false;\n}\n\nclass SafariServiceBuilder extends BaseService {\n  static get serviceName() {\n    return 'SafariDriver';\n  }\n\n  get requiresDriverBinary() {\n    return false;\n  }\n\n  get outputFile() {\n    return this._outputFile + '_safaridriver.log';\n  }\n\n  /**\n   * Port will be auto generated and probed by selenium\n   * @returns {number}\n   */\n  get defaultPort() {\n    return 0;\n  }\n\n  get serviceName() {\n    return SafariServiceBuilder.serviceName;\n  }\n\n  /**\n   * @param {Capabilities} options\n   * @returns {Promise<void>}\n   */\n  async createService(options) {\n    if (useTechnologyPreview(options.get(OPTIONS_CAPABILITY_KEY))) {\n      this.settings.webdriver.server_path = SAFARIDRIVER_TECHNOLOGY_PREVIEW_EXE;\n    }\n\n    this.service = new safari.ServiceBuilder(this.settings.webdriver.server_path);\n\n    if (Array.isArray(this.cliArgs)) {\n      this.service.addArguments(...this.cliArgs);\n    }\n\n    return super.createService(options);\n  }\n}\n\nmodule.exports = SafariServiceBuilder;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/service-builders/selenium.js",
    "content": "const path = require('path');\nconst {SeleniumServer, DriverService} = require('selenium-webdriver/remote');\nconst {isObject, isUndefined, isDefined, getFreePort} = require('../../../utils');\nconst BaseService = require('./base-service.js');\n\nclass SeleniumServer4 extends DriverService {\n  constructor(jar, opt_options) {\n    const options = opt_options || {};\n    const {command = 'standalone', jvmArgs, args} = options;\n    let combinedArgs = jvmArgs.concat('-jar', jar, command);\n\n    const port = options.port;\n    if (!args.includes('--port')) {\n      args.unshift('--port', port);\n    }\n\n    combinedArgs = combinedArgs.concat(args);\n\n    let java = 'java';\n    if (process.env['JAVA_HOME']) {\n      java = path.join(process.env['JAVA_HOME'], 'bin/java');\n    }\n\n    super(java, {\n      loopback: options.loopback,\n      port,\n      args: combinedArgs,\n      path: '/wd/hub',\n      env: options.env,\n      stdio: options.stdio\n    });\n  }\n}\n\nclass SeleniumServiceBuilder extends BaseService {\n  static get serviceName() {\n    return 'Selenium Server';\n  }\n\n  static get defaultPort() {\n    return 4444;\n  }\n\n  get npmPackageName() {\n    return '@nightwatch/selenium-server';\n  }\n\n  get outputFile() {\n    return this._outputFile + '_selenium-server.log';\n  }\n\n  get defaultPort() {\n    return SeleniumServiceBuilder.defaultPort;\n  }\n\n  get serviceName() {\n    return 'Selenium Server';\n  }\n\n  get serviceDownloadUrl() {\n    return 'https://selenium.dev/download/';\n  }\n\n  get downloadMessage() {\n    return `download the selenium server jar from ${this.serviceDownloadUrl}, \\n and set ` +\n      '\"selenium.server_path\" config option to point to the jar file.';\n  }\n\n  setCliArgs() {\n    const {cli_args, jvmArgs} = this.settings.selenium;\n    let cliArgs = jvmArgs || cli_args;\n\n    if (Array.isArray(cliArgs)) {\n      return super.setCliArgs(cliArgs);\n    }\n\n    this.jvmArgs = [];\n\n    if (isObject(cliArgs)) {\n      Object.keys(cliArgs).forEach(key => {\n        if (!isUndefined(cliArgs[key])) {\n          let property = '';\n          let isJvmArg = !key.startsWith('-');\n\n          if (isJvmArg) {\n            property += '-D';\n          }\n\n          property += key;\n\n          if (!cliArgs[key]) {\n            this.cliArgs.unshift(property);\n\n            return;\n          }\n\n          if (isJvmArg) {\n            this.jvmArgs.unshift(`${property}=${cliArgs[key]}`);\n          } else {\n            this.cliArgs.unshift(property, cliArgs[key]);\n          }\n\n        }\n      });\n    }\n  }\n\n  usingSelenium4() {\n    const {command, server_path} = this.settings.webdriver;\n\n    return isDefined(command) && !server_path.includes('selenium-server-standalone-3.');\n  }\n\n  /**\n   * @param {Capabilities} opts\n   * @returns {Promise<void>}\n   */\n  async createService(opts = {}) {\n    const {port} = this;\n    const options = new SeleniumServer.Options();\n    options.port = port || await getFreePort();\n    let {server_path, command} = this.settings.webdriver;\n\n    let commandStr = '';\n    if (command) {\n      commandStr = ` in ${command} mode `;\n    }\n    let serverPathStr = server_path.split(path.sep).pop();\n    const introMsg = `Starting Selenium Server [${serverPathStr}] on port ${options.port}${commandStr}...`;\n\n    if (opts.showSpinner) {\n      opts.showSpinner(`${introMsg}\\n\\n`);\n    } else {\n      // eslint-disable-next-line\n      console.info(introMsg);\n    }\n\n    // TODO: read the log_path and add it to cliArgs\n    options.args = this.cliArgs;\n    options.jvmArgs = this.jvmArgs;\n\n    if (this.hasSinkSupport() && this.needsSinkProcess()) {\n      this.createSinkProcess();\n      options.stdio = ['pipe', this.process.stdin, this.process.stdin];\n    }\n\n    let Constructor = SeleniumServer;\n    if (this.usingSelenium4()) {\n      options.command = command;\n      Constructor = SeleniumServer4;\n    }\n\n    this.service = new Constructor(server_path, options);\n\n    return this.service.start();\n  }\n}\n\nmodule.exports = SeleniumServiceBuilder;\n"
  },
  {
    "path": "lib/transport/selenium-webdriver/session.js",
    "content": "module.exports = class Session {\n  static get WEB_ELEMENT_ID () {\n    return 'element-6066-11e4-a52e-4f735466cecf';\n  }\n\n  static serializeCapabilities(caps) {\n    const ret = {};\n    for (const key of caps.keys()) {\n      const cap = caps.get(key);\n      if (cap !== undefined && cap !== null) {\n        ret[key] = cap;\n      }\n    }\n\n    return ret;\n  }\n\n  constructor(driver) {\n    this.driver = driver;\n  }\n\n  async exported() {\n    const session = await this.driver.getSession();\n    const sessionId = await session.getId();\n    const sessionCapabilities = await session.getCapabilities();\n    const platform = sessionCapabilities.getPlatform() || sessionCapabilities.get('platform') || '';\n    const platformVersion = sessionCapabilities.get('platformVersion') || '';\n    const browserName = sessionCapabilities.getBrowserName();\n    const browserVersion = sessionCapabilities.getBrowserVersion() || sessionCapabilities.get('version') || '';\n    const appId = sessionCapabilities.get('appPackage') || sessionCapabilities.get('bundleId') || '';\n\n    const executor = await this.driver.getExecutor();\n    const elementKey = executor.w3c ? Session.WEB_ELEMENT_ID : 'ELEMENT';\n\n    return {\n      sessionId,\n      elementKey,\n      sessionInfo: {\n        platform,\n        platformVersion,\n        browserName,\n        browserVersion,\n        appId\n      },\n      capabilities: Session.serializeCapabilities(sessionCapabilities)\n    };\n  }\n};\n"
  },
  {
    "path": "lib/utils/addDetailedError.js",
    "content": "/**\n * @method addDetailedError\n * @param {Error} err\n */\nmodule.exports = function(err) {\n  let detailedErr;\n\n  if (err instanceof TypeError) {\n    if (err.detailedErr && /browser\\..+ is not a function$/.test(err.detailedErr)) {\n      detailedErr = ' ' + err.detailedErr + '\\n\\n  Nightwatch client is not yet available; this often happens when you are attempting to reference the \"browser\" ' +\n        'object globally too soon, either in your test or other Nightwatch related files';\n    } else if (/\\.page\\..+ is not a function$/.test(err.message)) {\n      detailedErr = '- verify if page objects are setup correctly, check \"page_objects_path\" in your config';\n    } else if (err.message.includes('.mountComponent() is already defined.')) {\n      detailedErr = '  - running component tests? loading multiple plugins together is not supported.';\n      err.help = [\n        'check your nightwatch config file (e.g. nightwatch.conf.js) and inspect the line with \"plugins\": [...]',\n        'make sure to load only the plugin for the intended framework (e.g. either load @nightwatch/react or @nightwatch/vue, but not both together)'\n      ];\n\n      err.link = 'https://nightwatchjs.org/guide/concepts/component-testing.html';\n    } else if (err.message.includes('browser.mountComponent is not a function')) {\n      detailedErr = '  - writing an ES6 async test case? - keep in mind that commands return a Promise; \\n      - writing unit tests? - make sure to specify \"unit_tests_mode=true\" in your config.';\n    } else if (/\\w is not a function$/.test(err.message)) {\n      detailedErr = '  - writing an ES6 async test case? - keep in mind that commands return a Promise; \\n      - writing unit tests? - make sure to specify \"unit_tests_mode=true\" in your config.';\n    }\n  } else if (err instanceof SyntaxError) {\n    const stackParts = err.stack.split('SyntaxError:');\n    detailedErr = stackParts[0];\n    let modulePath = err.stack.split('\\n')[0];\n    if (modulePath.includes(':')) {\n      modulePath = modulePath.split(':')[0];\n    }\n\n    if (stackParts[1]) {\n      if (detailedErr) {\n        err.stack = '';\n      }\n\n      let header = stackParts[1].split('\\n')[0];\n      if (header.trim() === err.message) {\n        header = '';\n      } else {\n        header = header + ':\\n\\n  ';\n      }\n      detailedErr = header + detailedErr;\n    }\n\n    if (modulePath.endsWith('.jsx') || modulePath.endsWith('.tsx')) {\n      detailedErr = `\\n   In order to be able to load JSX files, one of these plugins is needed:\n   - @nightwatch/react\n   - @nightwatch/storybook (only if using Storybook in your project)\n      `;\n    }\n  }\n\n  if (detailedErr) {\n    err.detailedErr = detailedErr;\n  }\n};\n"
  },
  {
    "path": "lib/utils/alwaysDisplayError.js",
    "content": "module.exports = function(err) {\n  return (err instanceof Error) && [\n    'TypeError', 'SyntaxError', 'ReferenceError', 'RangeError'\n  ].includes(err.name);\n};\n"
  },
  {
    "path": "lib/utils/analytics.js",
    "content": "\n/** Parts of the code are taken from angular-cli code base which is governed by the following license:\n * https://angular.io/license\n */\n\nconst os = require('os');\nconst https = require('https');\nconst uuid = require('uuid');\nconst fs = require('fs').promises;\n\nconst path = require('path');\nconst {execSync} = require('child_process');\nconst {Logger, VERSION, fileExists} = require('./');\n\nconst GA_SERVER_URL = 'https://www.google-analytics.com';\nconst GA_SERVER_PORT = '443';\nconst GA_API_KEY = 'XuPojOTwQ6yTO758EV4hBg';\nconst GA_TRACKING_ID = 'G-DEKPKZSLXS';\n\nconst defaultSettings = {\n  enabled: false,\n  log_path: './logs/analytics',\n  client_id: uuid.v4()\n};\n\nconst RESERVED_EVENT_NAMES = ['ad_activeview', 'ad_click', 'ad_exposure', 'ad_impression', 'ad_query', 'adunit_exposure',\n  'app_clear_data', 'app_install', 'app_update', 'app_remove', 'error', 'first_open', 'first_visit', 'in_app_purchase',\n  'notification_dismiss', 'notification_foreground', 'notification_open', 'notification_receive', 'os_update',\n  'screen_view', 'session_start', 'user_engagement'];\n\nconst ALLOWED_ERRORS = ['Error', 'SyntaxError', 'TypeError', 'ReferenceError', 'WebDriverError', 'TimeoutError', 'NotFoundError', 'NoSuchElementError',\n  'IosSessionNotCreatedError', 'AndroidConnectionError', 'AndroidBinaryError', 'RealIosDeviceIdError', 'AndroidHomeError'];\n\nconst RESERVED_EVENT_PARAMETERS = ['firebase_conversion'];\n\nconst MAX_PARAMETERS_LENGTH = 40;\n\nconst SYSTEM_LANGUAGE = getLanguage();\n\n/**\n * See: https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide\n */\nclass AnalyticsCollector {\n  constructor() {\n    this.queueLength = 0;\n    this.parameters = {};\n    this.logger = Logger;\n    this.userAgentString = buildUserAgentString();\n    this.runId = uuid.v4();\n\n    // This identifies unique users and helps us separate out sessions.\n    this.parameters['client_id'] = uuid.v4();\n\n    // Prevents google from indexing the events for ad targeting.\n    this.parameters['non_personalized_ads'] = true;\n  }\n\n  initialize() {\n    if (this.initialized) {return this.initialized}\n\n    this.initialized = new Promise((resolve) => {\n      // update queueLength\n      fs.stat(this.__getLogFileLocation())\n        .then((length) => {\n          this.queueLength = length.size / 400; // the actual value doesn't matter\n          resolve();\n        })\n        .catch((err)=>{\n          // ignore error\n          resolve();\n        });\n    });\n\n    return this.initialized;\n  }\n\n  updateSettings(settings) {\n    this.settings = settings;\n\n    if (!this.settings.usage_analytics) {\n      this.settings.usage_analytics = defaultSettings;\n    }\n\n    this.testEnv = settings.testEnv;\n    // update client_id\n    this.parameters['client_id'] = this.settings.usage_analytics.client_id;\n  }\n\n  updateLogger(logger) {\n    this.logger = logger;\n  }\n\n  async collectEvent(name, parameters = {}) {\n    if (!this.settings.usage_analytics.enabled) {\n      return;\n    }\n\n    await this.initialize();\n\n    // Not all shape of events are supported.\n    this.__validateEvent(name, parameters);\n\n    // Add event timestamp.\n    parameters['event_time'] = new Date().getTime() * 1000;\n\n    // Add environment information.\n    parameters['env_os'] = this.userAgentString;\n    parameters['env_lang'] = SYSTEM_LANGUAGE;\n    parameters['env_nw_version'] = VERSION.full;\n    parameters['env_node_version'] = `node ${process.version}`;\n    parameters['test_env'] = this.testEnv;\n    parameters['run_id'] = this.runId;\n\n    return await this.__addToQueue(name, parameters);\n  }\n\n  async collectErrorEvent(error, isUncaught = false) {\n    if (!error) {\n      return;\n    }\n\n    await this.initialize();\n\n    let errorName = error.name;\n    if (!ALLOWED_ERRORS.includes(errorName)) {\n      errorName = 'UserGeneratedError';\n    }\n\n    try {\n      const parameters = {\n        env_os: this.userAgentString,\n        env_nw_version: VERSION.full,\n        env_node_version: `node ${process.version}`,\n        test_env: this.testEnv,\n        err_name: errorName,\n        is_uncaught: isUncaught,\n        run_id: this.runId\n      };\n\n      this.__validateEvent('nw_test_err', parameters);\n\n      await this.__addToQueue('nw_test_err', parameters);\n\n      if (isUncaught) {\n        await this.__flush();\n      }\n    } catch (e) {\n      // Ignore\n    }\n  }\n\n  async __flush() {\n    if (!this.settings.usage_analytics.enabled) {\n      return;\n    }\n\n    if (this.queueLength === 0) {\n      return;\n    }\n\n    try {\n      const logfile = this.__getLogFileLocation();\n\n      const pendingLogs =  await fs.readFile(logfile, 'utf8');\n      // The below is needed so that if flush is called multiple times,\n      // we don't report the same event multiple times.\n      await fs.truncate(logfile);\n      this.queueLength = 0;\n\n      const pendingLogsArray = pendingLogs.split('\\n');\n      pendingLogsArray.pop();\n      const pendingTrackingEvents = pendingLogsArray.map(log => JSON.parse(log));\n\n      // Time when the request is sent, expected in micro seconds.\n      const timestamp_micros = new Date().getTime() * 1000;\n\n      const payload = {\n        ...this.parameters,\n        timestamp_micros,\n        events: pendingTrackingEvents\n      };\n\n      await this.__send(payload);\n    } catch (error) {\n      // Failure to report analytics shouldn't crash the system.\n      this.logger.info('Analytics flush error:', error.message);\n    }\n  }\n\n  async __addToQueue(eventType, parameters) {\n    if (!this.settings.usage_analytics.enabled) {\n      return;\n    }\n\n    this.queueLength++;\n    const writeLogPromise = await this.__logAnalyticsEvents({name: eventType, params: parameters});\n\n    // periodically flush\n    if (this.queueLength > 5) {\n      await this.__flush();\n    }\n\n    return writeLogPromise;\n  }\n\n  async __send(data) {\n    if (!this.settings.usage_analytics.enabled) {\n      return;\n    }\n\n    this.logger.info('Analytics send event:', data);\n\n    const path = this.__getGoogleAnalyticsPath();\n\n    const serverUrl = new URL(this.settings.usage_analytics.serverUrl || GA_SERVER_URL) ;\n    const serverPort = serverUrl.port || this.settings.usage_analytics.serverPort || GA_SERVER_PORT;\n\n    const payload = JSON.stringify(data);\n\n    const request = new https.request({\n      hostname: serverUrl.hostname,\n      port: serverPort,\n      method: 'POST',\n      path,\n      headers: {\n        'Content-Type': 'application/json',\n        'Content-Length': payload.length\n      }\n    });\n\n    return new Promise((resolve, reject) => {\n      request.write(payload);\n\n      request.once('response', (response) => {\n        if (response.statusCode !== 204) {\n          reject(\n            new Error(`Analytics reporting failed with status code: ${response.statusCode}.`)\n          );\n        } else {\n          resolve(response);\n        }\n\n        response.on('data', (_) => {});\n      });\n\n      request.on('error', (result) => {\n        new Error(`Failed to send usage metric: ${result.code}.`);\n        reject(result);\n      });\n\n      request.end();\n    });\n  }\n\n  __getGoogleAnalyticsPath() {\n    const apiKey = this.settings.usage_analytics.apiKey || GA_API_KEY;\n    const trackingId = this.settings.usage_analytics.trackingId || GA_TRACKING_ID;\n\n    return `/mp/collect?api_secret=${apiKey}&measurement_id=${trackingId}`;\n  }\n\n  async __logAnalyticsEvents(data) {\n    const logfile = this.__getLogFileLocation();\n\n    const hasAnalyticsLog = await fileExists(logfile);\n\n    if (!hasAnalyticsLog) {\n      data.params = data.params ? data.params : {};\n      data.params['first_run'] = true;\n\n      await fs.mkdir(path.dirname(logfile), {recursive: true});\n    }\n\n    const writeFn = hasAnalyticsLog ? fs.appendFile : fs.writeFile;\n\n    try {\n      await writeFn(logfile, JSON.stringify(data) + '\\n');\n\n      // Always send data for first runs, this helps us detect CI builds also.\n      if (!hasAnalyticsLog) {\n        await this.__flush();\n      }\n    } catch (err) {\n      this.logger.warn('Failed to log usage data:', err.message);\n    }\n  }\n\n  __getLogFileLocation() {\n    const log_path = this.settings.usage_analytics.log_path || './logs/analytics';\n\n    return path.resolve(log_path, 'analytics.log');\n  }\n\n  __validateEvent(name, parameters) {\n\n    Object.keys(parameters).forEach(key => {\n      if (parameters[key] === undefined || parameters[key] === null) {\n        parameters[key] = 'undefined';\n      }\n    });\n\n    if (RESERVED_EVENT_NAMES.includes(name)) {\n      throw Error(`Analytics event name ${name} is reserved.`);\n    }\n\n    Object.keys(parameters).forEach(key => {\n      if (RESERVED_EVENT_PARAMETERS.includes(key)) {\n        throw Error(`Parameter name ${key} is reserved.`);\n      }\n\n      if (typeof parameters[key] === 'object') {\n        throw Error(`Parameter ${key} is an object. Only string and integer allowed.`);\n      }\n    });\n\n    if (parameters.length > MAX_PARAMETERS_LENGTH) {\n      throw Error(`Too many parameters. Maximum allowed is ${MAX_PARAMETERS_LENGTH}.`);\n    }\n  }\n}\n\n/**\n * Get a language code.\n */\nfunction getLanguage() {\n  return (process.env.LANG || // Default Unix env variable.\n    process.env.LC_CTYPE || // For C libraries. Sometimes the above isn't set.\n    process.env.LANGSPEC || // For Windows, sometimes this will be set (not always).\n    getWindowsLanguageCode() ||\n    '??');\n}\n\n/**\n * Attempt to get the Windows Language Code string.\n */\nfunction getWindowsLanguageCode() {\n  if (!os.platform().startsWith('win')) {\n    return undefined;\n  }\n\n  try {\n    // This is true on Windows XP, 7, 8 and 10 AFAIK. Would return empty string or fail if it\n    // doesn't work.\n    return execSync('wmic.exe os get locale').toString().trim();\n  } catch (err) {;}\n\n  return undefined;\n}\n\n/**\n * Build a fake User Agent string. This gets sent to Analytics so it shows the proper OS version.\n */\nfunction buildUserAgentString() {\n  const cpus = os.cpus();\n  const cpuModel = cpus.length > 1 ? cpus[0].model : 'NA';\n\n  return `${os.platform()}/${os.release()}/${cpuModel}`;\n}\n\n// export singleton instance\nmodule.exports = new AnalyticsCollector();;\n"
  },
  {
    "path": "lib/utils/beautifyStackTrace.js",
    "content": "const fs = require('fs');\nconst stackTraceParser = require('stacktrace-parser');\nconst AssertionError = require('assertion-error');\nconst {filterStackTrace} = require('./stackTrace.js');\nconst alwaysDisplayError = require('./alwaysDisplayError');\nconst {colors} = require('./chalkColors.js');\n\n/**\n * Read the User file from the stackTrace and create a string with highlighting the line with error\n * @param {Error} err\n */\nfunction beautifyStackTrace(err, errStackPassed = false, modulepath, cli = true) {\n  if ((err instanceof AssertionError) || alwaysDisplayError(err) || errStackPassed) {\n    try {\n      const errorStack = errStackPassed ? err : err.stack;\n\n      const parsedStacks = stackTraceParser.parse(filterStackTrace(errorStack));\n      let parsedStack = modulepath ? parsedStacks.find(o => o.file === modulepath) : parsedStacks[0];\n\n      if (!parsedStack) {\n        parsedStack = parsedStacks[0];\n      }\n\n      const file = fs.readFileSync(parsedStack.file, 'utf-8');\n      const errorLinesofFile = file.split(/\\r?\\n/);\n\n      const formattedStack = formatStackTrace(errorLinesofFile, parsedStack);\n      if (!cli) {\n        return formattedStack;\n      }\n\n      const desiredLines = formattedStack.codeSnippet.reduce(function(lines, newLine) {\n        const currentLine = newLine.line_number;\n        if (currentLine === formattedStack.error_line_number) {\n          lines += '\\n    ' + colors.bgRed.white(` ${currentLine} | ${newLine.code} `);\n        } else if (currentLine <= (formattedStack.error_line_number + 2) && currentLine >= (formattedStack.error_line_number - 2)) {\n          lines += `\\n     ${currentLine} | ${newLine.code}`;\n        }\n\n        return lines;\n      }, '');\n\n      const delimiter = (new Array(parsedStack.file.length + 3).join('–'));\n\n      return '    '  + parsedStack.file + `:${formattedStack.error_line_number}\\n    ` + delimiter + desiredLines + '\\n    ' + delimiter + '\\n';\n    } catch (err) {\n      return '';\n    }\n  }\n\n  return '';\n}\n\n/**\n * Read the User file from the stackTrace and create a string with highlighting the line with error\n * @param {Error} err\n */\nfunction formatStackTrace(errorLinesofFile, parsedStack) {\n\n  const result = {\n    filePath: parsedStack.file,\n    error_line_number: parsedStack.lineNumber,\n    codeSnippet: []\n  };\n\n  errorLinesofFile.reduce(function(lines, newLine, lineIndex) {\n    const currentLine = lineIndex + 1;\n    if (currentLine <= (parsedStack.lineNumber + 2) && currentLine >= (parsedStack.lineNumber - 2)) {\n      result.codeSnippet.push({\n        line_number: currentLine, code: newLine\n      });\n    }\n  }, '');\n\n\n  return result;\n\n}\n\nmodule.exports = beautifyStackTrace;\n\n"
  },
  {
    "path": "lib/utils/browsername.js",
    "content": "const BrowserName = module.exports = {\n  get CHROME() {\n    return 'chrome';\n  },\n\n  get FIREFOX() {\n    return 'firefox';\n  },\n\n  get SAFARI() {\n    return 'safari';\n  },\n\n  get EDGE() {\n    return 'MicrosoftEdge';\n  },\n\n  get INTERNET_EXPLORER() {\n    return 'internet explorer';\n  },\n\n  get OPERA() {\n    return 'opera';\n  }\n};\n\nObject.freeze(BrowserName);\n"
  },
  {
    "path": "lib/utils/chalkColors.js",
    "content": "const chalk = require('chalk');\n\nclass ChalkColors {\n  constructor() {\n    this.instance = new chalk.Instance();\n    this.origLevel = this.instance.level;\n\n    this.loadCustomColors(); // for backward compatibility\n\n    if (process.env.COLORS === '0') {\n      this.disable();\n    }\n  }\n\n  loadCustomColors() {\n    const colorsInstance = this.instance;\n\n    // foreground colors\n    colorsInstance.dark_gray = colorsInstance.black.bold;\n    colorsInstance.light_blue = colorsInstance.blue.bold;\n    colorsInstance.light_green = colorsInstance.green.bold;\n    colorsInstance.light_cyan = colorsInstance.cyan.bold;\n    colorsInstance.light_red = colorsInstance.red.bold;\n    colorsInstance.light_purple = colorsInstance.magenta.bold;\n    colorsInstance.light_gray = colorsInstance.white;\n\n    colorsInstance.purple = colorsInstance.magenta;\n    colorsInstance.brown = colorsInstance.yellow;\n    colorsInstance.stack_trace = colorsInstance.gray;\n  }\n\n  get colors() {\n    return this.instance;\n  }\n\n  get colorsEnabled() {\n    return this.instance.level !== 0;\n  }\n\n  disable() {\n    this.prevLevel = this.instance.level;\n    this.instance.level = 0;\n  }\n\n  enable() {\n    this.instance.level = this.prevLevel;\n  }\n\n  reset() {\n    this.instance.level = this.origLevel;\n  }\n}\n\nmodule.exports = new ChalkColors();\n"
  },
  {
    "path": "lib/utils/createPromise.js",
    "content": "/**\n * @return {{resolve, reject, promise}}\n */\nmodule.exports = function createPromise() {\n  const deferred = {\n    resolve: null,\n    reject: null,\n    promise: null\n  };\n\n  deferred.promise = new Promise((resolve, reject) => {\n    deferred.resolve = resolve;\n    deferred.reject = reject;\n  });\n\n  return deferred;\n};\n"
  },
  {
    "path": "lib/utils/debuggability.js",
    "content": "class Debuggability {\n  static get stepOverAndPause() {\n    return this._stepOverAndPause || false;\n  }\n\n  static set stepOverAndPause(value) {\n    this._stepOverAndPause = value;\n  }\n\n  static reset() {\n    this._stepOverAndPause = false;\n  }\n\n  static get debugMode() {\n    return this._debugMode;\n  }\n\n  static set debugMode(value) {\n    this._debugMode = value;\n  }\n}\n\nmodule.exports = Debuggability;\n"
  },
  {
    "path": "lib/utils/getAllClassMethodNames.js",
    "content": "const reserved = [\n  'constructor',\n  'isPrototypeOf',\n  'propertyIsEnumerable',\n  'toString',\n  'valueOf',\n  'toLocaleString'\n];\n\nconst isObjectPrototype = (item) => {\n  return item.constructor.name === 'Object' && Object.getPrototypeOf(item) === null;\n};\n\nmodule.exports = function(instance, additionalReserved = []) {\n  const result = new Set();\n\n  while (instance && !isObjectPrototype(instance)) {\n    Object.getOwnPropertyNames(instance).forEach(p => {\n      if ((typeof instance[p] == 'function') && !reserved.includes(p) && !additionalReserved.includes(p)) {\n        result.add(p);\n      }\n    });\n    instance = Object.getPrototypeOf(instance);\n  }\n\n  return [...result];\n};\n"
  },
  {
    "path": "lib/utils/getFreePort.js",
    "content": "/**\n * @method getFreePort\n * @param host\n * @returns {Promise<number>}\n */\nmodule.exports = function(host = 'localhost') {\n  const net = require('net');\n\n  return new Promise((resolve, reject) => {\n    const server = net.createServer();\n\n    server.on('listening', function () {\n      const serverAddress = server.address();\n\n      if (!serverAddress || typeof serverAddress === 'string') {\n        reject(new Error('Unable to get port from server address.'));\n      } else {\n        resolve(serverAddress.port);\n      }\n\n      server.close();\n    });\n\n    server.on('error', (e) => {\n      let err;\n      if (e.code === 'EADDRINUSE' || e.code === 'EACCES') {\n        err = new Error('Unable to find a free port');\n      } else {\n        err = e;\n      }\n\n      reject(err);\n    });\n\n    // By providing 0 we let the operative system find an arbitrary port\n    server.listen(0, host);\n  });\n};\n"
  },
  {
    "path": "lib/utils/index.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst glob = require('glob');\nconst lodashMerge = require('lodash/merge');\nconst {By, Capabilities} = require('selenium-webdriver');\nconst {inspect} = require('util');\n\nconst Logger = require('./logger');\nconst BrowserName = require('./browsername');\nconst LocateStrategy = require('./locatestrategy.js');\nconst PeriodicPromise = require('./periodic-promise.js');\nconst createPromise = require('./createPromise');\nconst isErrorObject = require('./isErrorObject');\nconst alwaysDisplayError = require('./alwaysDisplayError');\nconst Screenshots = require('./screenshots.js');\nconst Snapshots = require('./snapshots.js');\nconst TimedCallback = require('./timed-callback.js');\nconst getFreePort = require('./getFreePort');\nconst requireModule = require('./requireModule.js');\nconst getAllClassMethodNames = require('./getAllClassMethodNames.js');\nconst VERSION = require('./version.js');\nconst printVersionInfo = require('./printVersionInfo.js');\nconst {filterStack, filterStackTrace, showStackTrace, stackTraceFilter, errorToStackTrace} = require('./stackTrace.js');\nconst beautifyStackTrace = require('./beautifyStackTrace.js');\nconst SafeJSON = require('./safeStringify.js');\nconst formatRegExp = /%[sdj%]/g;\nconst testSuiteNameRegxp = /(_|-|\\.)*([A-Z]*)/g;\nconst nameSeparatorRegxp = /(\\s|\\/)/;\n\nconst PrimitiveTypes = {\n  OBJECT: 'object',\n  FUNCTION: 'function',\n  BOOLEAN: 'boolean',\n  NUMBER: 'number',\n  STRING: 'string',\n  UNDEFINED: 'undefined'\n};\n\nclass Utils {\n  static get tsFileExt() {\n    return '.ts';\n  }\n\n  static get jsFileExt() {\n    return '.js';\n  }\n\n  static isObject(obj) {\n    return obj !== null && typeof obj == 'object';\n  }\n\n  static isFunction(fn) {\n    return typeof fn == PrimitiveTypes.FUNCTION;\n  }\n\n  static isBoolean(value) {\n    return typeof value == PrimitiveTypes.BOOLEAN;\n  }\n\n  static isNumber(value) {\n    return typeof value == PrimitiveTypes.NUMBER;\n  }\n\n  static isString(value) {\n    return typeof value == PrimitiveTypes.STRING;\n  }\n\n  static isUndefined(value) {\n    return typeof value == PrimitiveTypes.UNDEFINED;\n  }\n\n  static isDefined(value) {\n    return !Utils.isUndefined(value);\n  }\n\n  static isES6AsyncFn(fn) {\n    return Utils.isFunction(fn) && fn.constructor.name === 'AsyncFunction';\n  }\n\n  static enforceType(value, type) {\n    type = type.toLowerCase();\n\n    switch (type) {\n      case PrimitiveTypes.STRING:\n      case PrimitiveTypes.BOOLEAN:\n      case PrimitiveTypes.NUMBER:\n      case PrimitiveTypes.FUNCTION:\n        if (typeof value != type) {\n          throw new Error(`Invalid type ${typeof value} for value \"${value}\". Expecting \"${type}\" instead.`);\n        }\n\n        return;\n    }\n\n    throw new Error(`Invalid type ${type} for ${value}`);\n  }\n\n  static convertBoolean(value) {\n    if (Utils.isString(value) && (!value || value === 'false' || value === '0')) {\n      return false;\n    }\n\n    return Boolean(value);\n  }\n\n  static get symbols() {\n    let ok = String.fromCharCode(10004);\n    let fail = String.fromCharCode(10006);\n\n    if (process.platform === 'win32') {\n      ok = '\\u221A';\n      fail = '\\u00D7';\n    }\n\n    return {\n      ok: ok,\n      fail: fail\n    };\n  }\n\n  /**\n   * @param {object|string} definition\n   * @return {object}\n   */\n  static convertToElementSelector(definition) {\n    const selector = Utils.isString(definition) ? {selector: definition} : definition;\n\n    return selector;\n  }\n\n  static isElementGlobal(selector) {\n    return selector.webElementLocator instanceof By;\n  }\n\n  /**\n   * @param {object} definition\n   * @param {object} [props]\n   * @return {object}\n   */\n  static setElementSelectorProps(definition, props = {}) {\n    const selector = Utils.convertToElementSelector(definition);\n    if (!selector || Utils.isElementGlobal(selector)) {\n      return selector;\n    }\n\n    Object.keys(props).forEach(function(key) {\n      selector[key] = props[key];\n    });\n\n    return selector;\n  }\n\n  static formatElapsedTime(timeMs, includeMs = false) {\n    const seconds = timeMs / 1000;\n\n    return (seconds < 1 && timeMs + 'ms') ||\n      (seconds > 1 && seconds < 60 && (seconds + 's')) ||\n      (Math.floor(seconds / 60) + 'm' + ' ' + Math.floor(seconds % 60) + 's' + (includeMs ? (' / ' + timeMs + 'ms') : ''));\n  }\n\n  /**\n   * Wrap a synchronous function, turning it into an psuedo-async fn with a callback as\n   * the last argument if necessary. `asyncArgCount` is the expected argument\n   * count if `fn` is already asynchronous.\n   *\n   * @deprecated\n   * @param {number} asyncArgCount\n   * @param {function} fn\n   * @param {object} [context]\n   */\n  static makeFnAsync(asyncArgCount, fn, context) {\n    if (fn.length === asyncArgCount) {\n      return fn;\n    }\n\n    return function(...args) {\n      const done = args.pop();\n      context = context || null;\n      fn.apply(context, args);\n      done();\n    };\n  }\n\n  static makePromise(handler, context, args) {\n    const result = Reflect.apply(handler, context, args);\n    if (result instanceof Promise) {\n      return result;\n    }\n\n    return Promise.resolve(result);\n  }\n\n  static checkFunction(name, parent) {\n    return parent && (typeof parent[name] == 'function') && parent[name] || false;\n  }\n\n  static getTestSuiteName(moduleName) {\n    moduleName = moduleName.replace(testSuiteNameRegxp, function(match, $0, $1, offset, string) {\n      if (!match) {\n        return '';\n      }\n\n      return (offset > 0 && (string.charAt(offset - 1) !== ' ') ? ' ' : '') + $1;\n    });\n\n    const words = moduleName.split(nameSeparatorRegxp).map(function(word, index, matches) {\n      if (word === '/') {\n        return '/';\n      }\n\n      return word.charAt(0).toUpperCase() + word.substr(1);\n    });\n\n    return words.join('');\n  }\n\n  /**\n   * A smaller version of util.format that doesn't support json and\n   * if a placeholder is missing, it is omitted instead of appended\n   *\n   * @param f\n   * @returns {string}\n   */\n  static format(message, selector, timeMS) {\n    return String(message).replace(formatRegExp, function(exp) {\n      if (exp === '%%') {\n        return '%';\n      }\n\n      switch (exp) {\n        case '%s':\n          return String(selector);\n\n        case '%d':\n          return Number(timeMS);\n\n        default:\n          return exp;\n      }\n    });\n  }\n\n  static getModuleKey(filePath, srcFolders, fullPaths) {\n    const modulePathParts = filePath.split(path.sep);\n    let diffInFolder = '';\n    let folder = '';\n    let parentFolder = '';\n    const moduleName = modulePathParts.pop();\n    filePath = modulePathParts.join(path.sep);\n\n    if (srcFolders) {\n      for (let i = 0; i < srcFolders.length; i++) {\n        folder = path.resolve(srcFolders[i]);\n        if (fullPaths.length > 1) {\n          parentFolder = folder.split(path.sep).pop();\n        }\n        if (filePath.indexOf(folder) === 0) {\n          diffInFolder = filePath.substring(folder.length + 1);\n          break;\n        }\n      }\n    }\n    parentFolder = this.isFileNameValid(parentFolder) ? '' : parentFolder;\n\n    return path.join(parentFolder, diffInFolder, moduleName);\n  }\n\n  static getOriginalStackTrace(commandFn) {\n    let originalStackTrace;\n\n    if (commandFn.stackTrace) {\n      originalStackTrace = commandFn.stackTrace;\n    } else {\n      const err = new Error;\n      Error.captureStackTrace(err, commandFn);\n      originalStackTrace = err.stack;\n    }\n\n    return originalStackTrace;\n  }\n\n  // util to replace deprecated fs.existsSync\n  static dirExistsSync(path) {\n    try {\n      return fs.statSync(path).isDirectory(); // eslint-disable-next-line no-empty\n    } catch (e) {}\n\n    return false;\n  }\n\n  static fileExistsSync(path) {\n    try {\n      return fs.statSync(path).isFile(); // eslint-disable-next-line no-empty\n    } catch (e) {}\n\n    return false;\n  }\n\n  static fileExists(path) {\n    return Utils.checkPath(path)\n      .then(function(stats) {\n        return stats.isFile();\n      })\n      .catch(function(err) {\n        return false;\n      });\n  }\n\n  static isTsFile(fileName){\n    return (path.extname(fileName) === Utils.tsFileExt);\n  }\n\n  static get validExtensions() {\n    return [\n      Utils.jsFileExt,\n      '.mjs',\n      '.cjs',\n      '.jsx',\n      Utils.tsFileExt,\n      '.cts',\n      '.mts',\n      '.tsx'\n    ];\n  }\n\n  static isFileNameValid(fileName) {\n    return Utils.validExtensions.includes(path.extname(fileName));\n  }\n\n  static checkPath(source, originalErr = null, followSymlinks = true) {\n    return new Promise(function(resolve, reject) {\n      if (glob.hasMagic(source)) {\n        return resolve();\n      }\n\n      fs[followSymlinks ? 'stat' : 'lstat'](source, function(err, stats) {\n        if (err) {\n          return reject(err.code === 'ENOENT' && originalErr || err);\n        }\n\n        resolve(stats);\n      });\n    });\n  }\n\n  /**\n   * @param {string} source\n   * @return {Promise}\n   */\n  static isFolder(source) {\n    return Utils.checkPath(source, null, false).then(stats => stats.isDirectory());\n  }\n\n  /**\n   * @param {string} source\n   * @return {Promise}\n   */\n  static readDir(source) {\n    return new Promise(function(resolve, reject) {\n      const callback = function(err, list) {\n        if (err) {\n          return reject(err);\n        }\n        resolve(list);\n      };\n\n      glob.hasMagic(source) ? glob(source, callback) : fs.readdir(source, callback);\n    });\n  }\n\n  /**\n   *\n   * @param {string} sourcePath\n   * @param {Array} namespace\n   * @param {function} loadFn\n   * @param {function} readSyncFn\n   */\n  static readFolderRecursively(sourcePath, namespace = [], loadFn, readSyncFn) {\n    let resources;\n    if (glob.hasMagic(sourcePath)) {\n      resources = glob.sync(sourcePath);\n    } else if (Utils.isFunction(readSyncFn)) {\n      const result = readSyncFn(sourcePath);\n      sourcePath = result.sourcePath;\n      resources = result.resources;\n    } else {\n      resources = fs.readdirSync(sourcePath);\n    }\n\n    resources.sort(); // makes the list predictable\n    resources.forEach(resource => {\n      if (path.isAbsolute(resource)) {\n        sourcePath = path.dirname(resource);\n        resource = path.basename(resource);\n      }\n\n      const isFolder = fs.lstatSync(path.join(sourcePath, resource)).isDirectory();\n      if (isFolder) {\n        const pathFolder = path.join(sourcePath, resource);\n        const ns = namespace.slice(0);\n        ns.push(resource);\n        Utils.readFolderRecursively(pathFolder, ns, loadFn);\n\n        return;\n      }\n\n      loadFn(sourcePath, resource, namespace);\n    });\n  }\n\n  static getPluginPath(pluginName) {\n    return path.resolve(require.resolve(pluginName, {\n      paths: [process.cwd()]\n    }));\n  }\n\n  static singleSourceFile(argv = {}) {\n    const {test, _source} = argv;\n\n    if (Utils.isString(test)) {\n      return Utils.fileExistsSync(test);\n    }\n\n    return Array.isArray(_source) && _source.length === 1 && Utils.fileExistsSync(_source[0]);\n  }\n\n  static getConfigFolder(argv) {\n    if (!argv || !argv.config) {\n      return '';\n    }\n\n    return path.dirname(argv.config);\n  }\n\n  /**\n   *\n   * @param {Array} arr\n   * @param {number} maxDepth\n   * @param {Boolean} includeEmpty\n   * @returns {Array}\n   */\n  static flattenArrayDeep(arr, maxDepth = 4, includeEmpty = false) {\n    if (!Array.isArray(arr)) {\n      throw new Error(`Utils.flattenArrayDeep excepts an array to be passed. Received: \"${arr === null ? arr : typeof arr}\".`);\n    }\n\n    return (function flatten(currentArray, currentDepth, initialValue = []) {\n      currentDepth = currentDepth + 1;\n\n      return currentArray.reduce(function(prev, value) {\n        if (Array.isArray(value)) {\n          const result = prev.concat(value);\n          if (Array.isArray(result) && currentDepth <= maxDepth) {\n            return flatten(result, currentDepth);\n          }\n\n          return result;\n        }\n\n        currentDepth = 0;\n\n        if (!includeEmpty && (value === null || value === undefined || value === '')) {\n          return prev;\n        }\n\n        prev.push(value);\n\n        return prev;\n      }, initialValue);\n    })(arr, 0);\n  }\n\n  /**\n   * Strips out all control characters from a string\n   * However, excludes newline and carriage return\n   *\n   * @param {string} input String to remove invisible chars from\n   * @returns {string} Initial input string but without invisible chars\n   */\n  static stripControlChars(input) {\n    return input && input.replace(\n      // eslint-disable-next-line no-control-regex\n      /[\\x00-\\x09\\x0B-\\x0C\\x0E-\\x1F\\x7F-\\x9F]/g,\n      ''\n    );\n  }\n\n  static relativeUrl(url) {\n    return !(url.includes('://'));\n  }\n\n  static uriJoin(baseUrl, uriPath) {\n    let result = baseUrl;\n\n    if (baseUrl.endsWith('/')) {\n      result = result.substring(0, result.length - 1);\n    }\n\n    if (!uriPath.startsWith('/')) {\n      result = result + '/';\n    }\n\n    return result + uriPath;\n  }\n\n  static replaceParams(url, params = {}) {\n    return Object.keys(params).reduce(function(prev, param) {\n      prev = prev.replace(`:${param}`, params[param]);\n\n      return prev;\n    }, url);\n  }\n\n  static createFolder(dirPath) {\n    return new Promise((resolve, reject) => {\n      Utils.mkpath(dirPath, function(err) {\n        if (err) {\n          return reject(err);\n        }\n\n        resolve();\n      });\n    });\n  }\n\n  /**\n   * Writes content to file. Creates parent folders if the folders do not exist.\n   * @param {string} filePath\n   * @param {string} data\n   */\n  static writeToFile(filePath, data, encoding = null) {\n    const dir = path.resolve(filePath, '..');\n\n    return new Promise((resolve, reject) => {\n      Utils.mkpath(dir, function(err) {\n        if (err) {\n          reject(err);\n        } else {\n          fs.writeFile(filePath, data, encoding, function(err) {\n            if (err) {\n              reject(err);\n            } else {\n              resolve(filePath);\n            }\n          });\n        }\n      });\n    });\n  }\n\n  static containsMultiple(arrayOrString, valueToFind, separator = ',') {\n    if (typeof valueToFind == 'string') {\n      valueToFind = valueToFind.split(separator);\n    }\n\n    if (Array.isArray(valueToFind)) {\n      if (valueToFind.length > 1) {\n        return valueToFind.every(item => arrayOrString.includes(item));\n      }\n\n      valueToFind = valueToFind[0];\n    }\n\n    return arrayOrString.includes(valueToFind);\n  }\n\n  static shouldReplaceStack(err) {\n    return !alwaysDisplayError(err);\n  }\n\n  static findTSConfigFile(existingTSConfig) {\n    const projectTsFileLocation1 = path.join(process.cwd(), 'nightwatch', 'tsconfig.json');\n    const projectTsFileLocation2 = path.join(process.cwd(), 'tsconfig.nightwatch.json');\n\n    if (Utils.fileExistsSync(existingTSConfig)) {\n      return existingTSConfig;\n    }\n\n    if (Utils.fileExistsSync(projectTsFileLocation1)) {\n      return projectTsFileLocation1;\n    }\n    if (Utils.fileExistsSync(projectTsFileLocation2)) {\n      return projectTsFileLocation2;\n    }\n\n    return '';\n  }\n\n  static loadTSNode(projectTsFile) {\n    try {\n      require('ts-node').register({\n        esm: false,\n        transpileOnly: true,\n        project: projectTsFile,\n        // Always compile and execute .ts files as CommonJS,\n        // even in ESM projects.\n        moduleTypes: {\n          '**/*.ts': 'cjs'\n        }\n      });\n    } catch (err) {\n      if (err.code === 'MODULE_NOT_FOUND') {\n        const error = new Error(`ts-node needs to be installed as a project dependency. You can install ts-node from NPM using:\\n\\n        ${Logger.colors.light_green('npm i ts-node --save-dev')}`);\n        error.showTrace = false;\n        error.displayed = false;\n\n        throw error;\n      }\n\n      err.showTrace = false;\n\n      throw err;\n    }\n  }\n\n  static isSafari(desiredCapabilities = {}) {\n    const browserName = desiredCapabilities.browserName || (desiredCapabilities instanceof Capabilities && desiredCapabilities.getBrowserName());\n\n    if (browserName && browserName.toLowerCase() === 'safari') {\n      return true;\n    }\n\n    return false;\n  }\n\n  static isChrome(desiredCapabilities = {}) {\n    const browserName = desiredCapabilities.browserName || (desiredCapabilities instanceof Capabilities && desiredCapabilities.getBrowserName());\n\n    if (browserName && browserName.toLowerCase() === 'chrome') {\n      return true;\n    }\n\n    return false;\n  }\n\n  static isLocalhost(webdriver = {}) {\n    const {host} = webdriver;\n\n    return ['127.0.0.1', 'localhost'].indexOf(host) > -1;\n  }\n\n  static setFunctionName(fn, name) {\n    Object.defineProperty(fn, 'name', {\n      value: name,\n      writable: false,\n      enumerable: false,\n      configurable: true\n    });\n\n    return fn;\n  }\n\n  static stringifyObject(objects) {\n    const objectString = Utils.isObject(objects) ? inspect(objects) : objects;\n\n    return `\"${objectString}\"`;\n  }\n\n  /**\n   * make all directories in a path, like mkdir -p\n   */\n  static mkpath(dirpath, mode, callback) {\n    dirpath = path.resolve(dirpath);\n\n    if (typeof mode === 'function' || typeof mode === 'undefined') {\n      callback = mode;\n      mode = parseInt('0777', 8);\n\n      if (!callback) {\n        callback = function() {};\n      }\n    }\n\n    fs.stat(dirpath, function (err, stats) {\n      if (err) {\n        if (err.code === 'ENOENT') {\n          Utils.mkpath(path.dirname(dirpath), mode, function (err) {\n            if (err) {\n              callback(err);\n            } else {\n              fs.mkdir(dirpath, mode, function (err) {\n                if (!err || err.code === 'EEXIST') {\n                  callback(null);\n                } else {\n                  callback(err);\n                }\n              });\n            }\n          });\n        } else {\n          callback(err);\n        }\n      } else if (stats.isDirectory()) {\n        callback(null);\n      } else {\n        callback(new Error(dirpath + ' exists and is not a directory'));\n      }\n    });\n  }\n}\n\nlodashMerge(Utils, {\n  PrimitiveTypes,\n  BrowserName,\n  LocateStrategy,\n  Logger,\n  isErrorObject,\n  requireModule,\n  createPromise,\n  getAllClassMethodNames,\n  SafeJSON,\n\n  filterStack,\n  filterStackTrace,\n  showStackTrace,\n  stackTraceFilter,\n  errorToStackTrace,\n\n  PeriodicPromise,\n  Screenshots,\n  Snapshots,\n  TimedCallback,\n\n  getFreePort,\n  VERSION,\n  printVersionInfo,\n\n  alwaysDisplayError,\n  beautifyStackTrace\n});\n\nmodule.exports = Utils;\n"
  },
  {
    "path": "lib/utils/isErrorObject.js",
    "content": "module.exports = function(err) {\n  return err instanceof Error || Object.prototype.toString.call(err) === '[object Error]';\n};\n"
  },
  {
    "path": "lib/utils/locatestrategy.js",
    "content": "const __RECURSION__ = 'recursion';\n\nclass LocateStrategy {\n  static get Strategies() {\n    return {\n      ID: 'id',\n      CSS_SELECTOR: 'css selector',\n      LINK_TEXT: 'link text',\n      PARTIAL_LINK_TEXT: 'partial link text',\n      TAG_NAME: 'tag name',\n      XPATH: 'xpath',\n      NAME: 'name',\n      CLASS_NAME: 'class name',\n      // Appium-specific strategies\n      ACCESSIBILITY_ID: 'accessibility id',\n      ANDROID_UIAUTOMATOR: '-android uiautomator',\n      IOS_PREDICATE_STRING: '-ios predicate string',\n      IOS_CLASS_CHAIN: '-ios class chain'\n    };\n  }\n\n  static isValid(strategy) {\n    return Object.keys(LocateStrategy.Strategies).some(key => {\n      return String(strategy).toLocaleLowerCase() === LocateStrategy.Strategies[key];\n    });\n  }\n\n  static getList() {\n    return Object.keys(LocateStrategy.Strategies).map(k => LocateStrategy.Strategies[k]).join(', ');\n  }\n\n  static get XPATH() {\n    return LocateStrategy.Strategies.XPATH;\n  }\n\n  static get CSS_SELECTOR() {\n    return LocateStrategy.Strategies.CSS_SELECTOR;\n  }\n\n  static getDefault() {\n    return LocateStrategy.CSS_SELECTOR;\n  }\n\n  static get Recursion() {\n    return __RECURSION__;\n  }\n}\n\nmodule.exports = LocateStrategy;\n"
  },
  {
    "path": "lib/utils/logger/index.js",
    "content": "const util = require('util');\nconst boxen = require('boxen');\nconst didYouMean = require('didyoumean');\nconst AssertionError = require('assertion-error');\nconst lodashEscape = require('lodash/escape');\n\nconst LogSettings = require('./log_settings.js');\nconst chalkColors = require('../chalkColors.js');\n\nconst addDetailedError = require('../addDetailedError.js');\n\nconst Errors = require('../../transport/errors');\nconst beautifyStackTrace = require('../beautifyStackTrace.js');\n\nconst alwaysDisplayError = require('../alwaysDisplayError.js');\n\nconst Severity = {\n  LOG: 'LOG',\n  INFO: 'INFO',\n  WARN: 'WARN',\n  ERROR: 'ERROR'\n};\n\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n  'Oct', 'Nov', 'Dec'];\n\nfunction pad(n) {\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\nlet __instance__;\n\n// 26 Feb 16:19:34\nfunction timestamp(d = new Date(), format) {\n  if (format === 'iso') {\n    return d.toISOString();\n  }\n\n  const time = [\n    pad(d.getHours()),\n    pad(d.getMinutes()),\n    pad(d.getSeconds())\n  ].join(':');\n\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\nfunction inspectObject(obj) {\n  return util.inspect(obj, {\n    showHidden: false,\n    depth: 4,\n    colors: chalkColors.colorsEnabled\n  })\n    .replace(/^\\s{2}/gm, '     ')\n    .replace(/^}$/m, '  }');\n}\n\nfunction logObject(obj) {\n  // eslint-disable-next-line no-console\n  console.log('  ', inspectObject(obj));\n}\n\nfunction logTimestamp(d) {\n  if (LogSettings.isLogTimestamp()) {\n    return chalkColors.colors.white.bold(timestamp(d, LogSettings.timestampFormat));\n  }\n\n  return '';\n}\n\nfunction logMessage(type, message, args, alwaysShow) {\n  if (!message || !LogSettings.outputEnabled || !LogSettings.enabled && !alwaysShow) {\n    return;\n  }\n\n  const colors = chalkColors.colors;\n  let messageStr = '';\n  let logMethod = 'log';\n  let prefix;\n  const d = new Date();\n  const timeIso = d.toISOString();\n  let timestamp = logTimestamp(d);\n\n  switch (type) {\n    case Severity.ERROR:\n      prefix = colors.bgBlack.yellow.bold(type);\n      // eslint-disable-next-line no-control-regex\n      messageStr = message.match(/\\u001b\\[.*?m/) ? message : colors.red.bold(message);\n      logMethod = 'error';\n      break;\n\n    case Severity.INFO:\n      prefix = colors.bgBlack.magenta.bold(type);\n      // eslint-disable-next-line no-control-regex\n      messageStr = message.match(/\\u001b\\[.*?m/) ? message : colors.cyan.bold(message);\n      break;\n\n    case Severity.LOG:\n      prefix = colors.bgBlack.white.bold(type + ' ');\n      // eslint-disable-next-line no-control-regex\n      messageStr = message.match(/\\u001b\\[.*?m/) ? message : colors.white.bold(message);\n      break;\n\n    case Severity.WARN:\n      prefix = colors.bgBlack.green.bold(type);\n      // eslint-disable-next-line no-control-regex\n      messageStr = message.match(/\\u001b\\[.*?m/) ? message : colors.green.bold(message);\n      logMethod = 'warn';\n      break;\n  }\n\n  if (LogSettings.timestampFormat === 'iso') {\n    let severity = type.toUpperCase();\n    if (severity === Severity.LOG) {\n      severity = Severity.INFO;\n    }\n\n    timestamp += ` ${severity} nightwatch:`;\n  }\n\n  // eslint-disable-next-line no-console\n  console[logMethod](timestamp, messageStr);\n\n  if (args.length > 0) {\n    let inlineArgs = [];\n    args.forEach(function(item) {\n      if (item === undefined) {\n        return;\n      }\n\n      if (Object.prototype.toString.call(item) === '[object Object]' && Object.keys(item).length > 0) {\n        if (inlineArgs.length) {\n          // eslint-disable-next-line no-console\n          console[logMethod](...inlineArgs);\n          inlineArgs = [];\n        }\n        logObject(item);\n      } else {\n        inlineArgs.push(item);\n      }\n    });\n\n    if (inlineArgs.length) {\n      // eslint-disable-next-line no-console\n      console[logMethod](...inlineArgs);\n      inlineArgs = [];\n    }\n  }\n}\n\nfunction findSuggestion({message} = {}) {\n  if (message && message.includes('is not a function')) {\n    const match = message.replace(' is not a function', '').replace('browser.', '');\n\n    if (match) {\n      const suggestion = didYouMean(match, ['element.findAll']);\n      if (suggestion) {\n        return suggestion;\n      }\n    }\n  }\n\n  return null;\n}\n\nfunction logRequest(message, params) {\n  if (!message || !LogSettings.htmlReporterEnabled) {\n    return;\n  }\n\n  const d = new Date();\n  const timeIso = d.toISOString();\n  const instance = Logger.getInstance();\n\n  instance.output.push([timeIso, lodashEscape(message), lodashEscape(inspectObject(params))]);\n  instance.commandOutput.push([timeIso, lodashEscape(message), lodashEscape(inspectObject(params))]);\n  instance.testSectionOutput.push([timeIso, lodashEscape(message), lodashEscape(inspectObject(params))]);\n  instance.testHooksOutput.push([timeIso, lodashEscape(message), lodashEscape(inspectObject(params))]);\n}\n\nfunction logError(severity, errOrMessage, args) {\n  const alwaysDisplay = LogSettings.isErrorLogEnabled() && severity === Severity.ERROR;\n  logMessage(severity, errOrMessage, args, alwaysDisplay);\n}\n\nclass Logger {\n  static getInstance() {\n    return __instance__;\n  }\n\n  constructor() {\n    this.colors = chalkColors.colors;\n\n    this.output = [];\n    this.commandOutput = [];\n    this.testSectionOutput = [];\n    this.testHooksOutput = [];\n  }\n\n  logMessage(...args) {\n    logMessage(...args);\n  }\n\n  inspectObject(obj) {\n    return inspectObject(obj);\n  }\n\n  info(message, ...args) {\n    logMessage('INFO', message, args);\n  }\n\n  log(message, ...args) {\n    logMessage('LOG', message, args);\n  }\n\n  warn(message, ...args) {\n    message = this.getErrorContent(message);\n    logError('WARN', message, args);\n  }\n\n  error(message, ...args) {\n    message = this.getErrorContent(message);\n    logError('ERROR', message, args);\n  }\n\n  request(message, params) {\n    logRequest(message, params);\n  }\n\n  response(message, params) {\n    logRequest(message, params);\n  }\n\n  underline(text) {\n    if (!this.colors) {\n      return text;\n    }\n\n    return '\\u{1b}[4m' + text + '\\u{1b}[24m';\n  }\n\n  setOptions(settings) {\n    this.setOutputEnabled(settings.output);\n    this.setHtmlReporterEnabled(typeof settings.output_folder == 'string');\n    this.setDetailedOutput(settings.detailed_output);\n    this.setLogTimestamp(settings.output_timestamp, settings.timestamp_format);\n    this.setErrorLog(settings.disable_error_log);\n\n    if (settings.disable_colors) {\n      this.disableColors();\n    }\n\n    if (settings.silent) {\n      this.disable();\n    } else {\n      this.enable();\n    }\n  }\n\n  disableColors() {\n    chalkColors.disable();\n  }\n\n  setHtmlReporterEnabled(value) {\n    LogSettings.htmlReporterEnabled = value;\n  }\n\n  disable() {\n    LogSettings.disable();\n  }\n\n  enable() {\n    LogSettings.enable();\n  }\n\n  setOutputEnabled(val = true) {\n    LogSettings.outputEnabled = val;\n  }\n\n  isOutputEnabled() {\n    return LogSettings.outputEnabled;\n  }\n\n  isHtmlReporterEnabled() {\n    return LogSettings.htmlReporterEnabled;\n  }\n\n  setDetailedOutput(val) {\n    LogSettings.detailedOutput = val;\n  }\n\n  isDetailedOutput() {\n    return LogSettings.outputEnabled && LogSettings.detailedOutput;\n  }\n\n  setLogTimestamp(val, format) {\n    LogSettings.setLogTimestamp(val, format);\n  }\n\n  setHttpLogOptions(opts) {\n    LogSettings.setHttpLogOptions(opts);\n  }\n\n  showRequestData() {\n    return LogSettings.showRequestData;\n  }\n\n  showResponseHeaders() {\n    return LogSettings.showResponseHeaders;\n  }\n\n  isLogTimestamp() {\n    return LogSettings.isLogTimestamp();\n  }\n\n  isErrorLogEnabled() {\n    return LogSettings.isErrorLogEnabled();\n  }\n\n  isEnabled() {\n    return LogSettings.enabled;\n  }\n\n  setErrorLog(val = false) {\n    LogSettings.disableErrorLog = val;\n  }\n\n  logDetailedMessage(message, type = 'log') {\n    if (!LogSettings.outputEnabled || !LogSettings.detailedOutput) {\n      return;\n    }\n\n    // eslint-disable-next-line no-console\n    console[type](message);\n  }\n\n  getFailedAssertions(assertions, modulepath) {\n    return assertions.reduce((prev, a) => {\n      if (a.failure !== false) {\n        prev.push(`   ${this.colors.red.bold('→') + this.getErrorContent(a, modulepath)}`);\n      }\n\n      return prev;\n    }, []).join('\\n');\n  }\n\n  isAssertionError(err) {\n    return (err instanceof AssertionError) || err.name === 'AssertionError' || err.name === 'NightwatchAssertError' || err.name === 'NightwatchMountError';\n  }\n\n  getErrorContent(error, modulepath) {\n    let errorObj;\n    if (this.isAssertionError(error)) {\n      errorObj = error;\n    } else {\n      errorObj = Errors.getErrorObject(error);\n    }\n\n    addDetailedError(errorObj, modulepath);\n\n    const content = [];\n\n    let errorTitle = ` ${this.colors.light_red(errorObj.name)}`;\n    if (this.isAssertionError(error) || alwaysDisplayError(error)) {\n      errorTitle = ` ${this.colors.red.bold('✖') + errorTitle}`;\n    }\n\n    const message = [];\n    if (errorObj.message || errorObj.fullMsg) {\n      let errorObjMessage = errorObj.message;\n      // eslint-disable-next-line no-control-regex\n      errorObjMessage = errorObjMessage.match(/\\u001b\\[.*?m/) ? errorObjMessage : this.colors.red(errorObjMessage);\n      message.push(errorObjMessage);\n\n      if (errorObj.detailedErr) {\n        message.push(this.colors.light_green(errorObj.detailedErr));\n\n        if (errorObj.extraDetail) {\n          message.push(this.colors.light_green(errorObj.extraDetail));\n        }\n      }\n    }\n\n    content.push(errorTitle);\n    const showStack = errorObj.showTrace || errorObj.showTrace === undefined;\n\n    if (!showStack && errorObj.reportShown) {\n      return ' ' + message.join('\\n ');\n    }\n\n    if (!showStack && !this.isAssertionError(error) && !error.help) {\n      return '\\n' + boxen(`${message.join('\\n')}\\n`, {padding: 1, borderColor: 'red'}) + '\\n';\n    }\n\n    const messageStr = message.join('\\n    ');\n    content.push(`   ${messageStr}`);\n\n    const suggestion = findSuggestion(error);\n    if (suggestion) {\n      errorObj.help = errorObj.help || [];\n      errorObj.help.unshift(' did you mean: ' + suggestion + '?');\n    }\n\n    if (errorObj.help) {\n      content.push(this.colors.brown('\\n    Try fixing by :'));\n      errorObj.help.forEach((step, index) => {\n        content.push(`    ${this.colors.blue(index + 1)}. ${step}`);\n      });\n    }\n\n    if (errorObj.link){\n      content.push(`\\n    ${this.colors.brown('Read More')} : \\n    ${this.colors.cyan(errorObj.link)} `);\n    }\n\n    let stack = error.stack || error.stackTrace;\n    if (stack && showStack) {\n      stack = '    at' + stack.split(/ {4}at/g).slice(1).join('    at');\n\n      const beautified = beautifyStackTrace(stack, true, modulepath);\n      if (beautified) {\n        content.push(this.colors.brown('\\n    Error location:'));\n        content.push(beautified);\n      }\n\n      if (alwaysDisplayError(errorObj)) {\n        content.push(this.colors.brown('    Stack Trace :'));\n        const coloredStack = stack.split('\\n').map((line) => this.colors.stack_trace(line)).join('\\n');\n        content.push(`${coloredStack}\\n`);\n      }\n    }\n\n    if (content.length === 2) {\n      if (content[0].includes('WebDriverError')) {\n        return content.join(this.colors.light_red(':'));\n      }\n\n      if (content[0].includes('Error') && content[1].includes('Error while')) {\n        const firstLine = content.shift();\n        content[0] = '  ' + firstLine + content[0];\n      }\n\n    }\n\n    return content.join('\\n');\n  }\n\n  formatMessage(msg, ...args) {\n    args = args.map(val => {\n      return this.colors.brown(val);\n    });\n\n    return util.format(msg, ...args);\n  }\n}\n\nmodule.exports = new (function() {\n  __instance__ = new Logger();\n\n  return Logger.getInstance();\n});\n\nconst getOutput = module.exports.getOutput = function() {\n  if (!Logger.getInstance()) {\n    return [];\n  }\n\n  const {output} = Logger.getInstance();\n\n  return output.slice(0);\n};\n\nmodule.exports.collectOutput = function() {\n  const instance = Logger.getInstance();\n\n  if (!instance) {\n    return [];\n  }\n\n  const output = getOutput();\n  instance.output = [];\n\n  return output;\n};\n\nmodule.exports.collectTestSectionOutput = function() {\n  const instance = Logger.getInstance();\n\n  if (!instance) {\n    return [];\n  }\n\n  const {testSectionOutput} = instance;\n  instance.testSectionOutput = [];\n\n  return testSectionOutput;\n};\n\nmodule.exports.collectCommandOutput = function() {\n  const instance = Logger.getInstance();\n\n  if (!instance) {\n    return [];\n  }\n\n  const {commandOutput} = instance;\n  instance.commandOutput = [];\n\n  return commandOutput;\n};\n\nmodule.exports.collectTestHooksOutput = function() {\n  const instance = Logger.getInstance();\n\n  if (!instance) {\n    return [];\n  }\n\n  const {testHooksOutput} = instance;\n  instance.testHooksOutput = [];\n\n  return testHooksOutput;\n};\nmodule.exports.reset = function() {\n  const instance = Logger.getInstance();\n\n  if (!instance) {\n    return;\n  }\n\n  instance.testSectionOutput = [];\n  instance.output = [];\n};\n"
  },
  {
    "path": "lib/utils/logger/log_settings.js",
    "content": "class LogSettings {\n  #outputEnabled;\n  #showResponseHeaders;\n  #showRequestData;\n  #detailedOutput;\n  #disableErrorLog;\n  #log_timestamp;\n  #timestamp_format;\n  #enabled;\n  #htmlReporterEnabled;\n\n  constructor() {\n    this.#outputEnabled = true;\n    this.#showResponseHeaders = false;\n    this.#showRequestData = {\n      enabled: true,\n      trimLongScripts: true\n    },\n    this.#detailedOutput = true;\n    this.#disableErrorLog = false;\n    this.#log_timestamp = false;\n    this.#timestamp_format = null;\n    this.#enabled = true;\n    this.#htmlReporterEnabled = false;\n  }\n\n  get outputEnabled() {\n    return this.#outputEnabled;\n  }\n\n  get detailedOutput() {\n    return this.#detailedOutput;\n  }\n\n  get showRequestData() {\n    return this.#showRequestData;\n  }\n\n  get enabled() {\n    return this.#enabled;\n  }\n\n  get showResponseHeaders() {\n    return this.#showResponseHeaders;\n  }\n\n  get timestampFormat() {\n    return this.#timestamp_format;\n  }\n\n  set outputEnabled(value) {\n    if (typeof value === 'undefined') {\n      value = true;\n    }\n\n    this.#outputEnabled = value;\n  }\n\n  set detailedOutput(value) {\n    this.#detailedOutput = value;\n  }\n\n  set disableErrorLog(value) {\n    if (typeof value === 'undefined') {\n      value = true;\n    }\n\n    this.#disableErrorLog = value;\n  }\n\n  set htmlReporterEnabled(value) {\n    this.#htmlReporterEnabled = value;\n  }\n\n  get htmlReporterEnabled() {\n    return this.#htmlReporterEnabled;\n  }\n\n  isLogTimestamp() {\n    return this.#log_timestamp;\n  }\n\n  isErrorLogEnabled() {\n    return !this.#disableErrorLog;\n  }\n\n  disable() {\n    this.#enabled = false;\n  }\n\n  enable() {\n    this.#enabled = true;\n  }\n\n  setLogTimestamp(val, format) {\n    this.#log_timestamp = val;\n    this.#timestamp_format = format;\n  }\n\n  setHttpLogOptions({showRequestData, showResponseHeaders}) {\n    this.#showRequestData = showRequestData;\n    this.#showResponseHeaders = showResponseHeaders;\n  }\n}\n\nmodule.exports = new LogSettings();\n"
  },
  {
    "path": "lib/utils/mobile.js",
    "content": "const {execSync} = require('child_process');\nconst Logger = require('./logger');\nconst untildify = require('untildify');\nconst path = require('path');\nconst semver = require('semver');\n\n/**\n * Function to require mobile-helper\n */\nfunction requireMobileHelper() {\n  try {\n    return require('@nightwatch/mobile-helper');\n  } catch (err) {\n    if (err.code === 'MODULE_NOT_FOUND') {\n      err.message = `@nightwatch/mobile-helper needs to be installed as a project dependency. You can install @nightwatch/mobile-helper from NPM using:\\n\\n        ${Logger.colors.light_green('npm i @nightwatch/mobile-helper --save-dev')}`;\n    } else if (!semver.satisfies(process.version, '>=14.0.0')) {\n      err.message = 'You are using Node ' + process.version + ', but @nightwatch/mobile-helper requires Node >= v14.0.0.\\nPlease upgrade your Node version.';\n    }\n\n    err.showTrace = false;\n    err.displayed = false;\n\n    throw err;\n  }\n}\n\n/**\n * check if target is Android\n * @param {Object} desiredCapabilities\n * @returns {Boolean}\n */\nfunction isAndroid(desiredCapabilities = {}){\n  const {platformName} = desiredCapabilities;\n\n  if (platformName && platformName.toLowerCase() === 'android') {\n    return true;\n  }\n\n  const options = desiredCapabilities['goog:chromeOptions'] || desiredCapabilities['moz:firefoxOptions'];\n\n  if (options && options.androidPackage) {\n    return true;\n  }\n\n  return false;\n};\n\n/**\n * check if target is iOS Device\n * @param {Object} desiredCapabilities\n * @returns {Boolean}\n */\nfunction isIos(desiredCapabilities = {}) {\n  const {platformName} = desiredCapabilities;\n\n  if (platformName && platformName.toLowerCase() === 'ios') {\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * check if target is Simulator\n * @param {Object} desiredCapabilities\n * @returns {Boolean}\n */\nfunction isSimulator(desiredCapabilities){\n  if (isIos(desiredCapabilities) && desiredCapabilities['safari:useSimulator'] === true) {\n    return true;\n  }\n\n  return false;\n};\n\n/**\n * check if target is Real iOS Device\n * @param {Object} desiredCapabilities\n * @returns {Boolean}\n */\nfunction isRealIos(desiredCapabilities) {\n  if (isIos(desiredCapabilities) && desiredCapabilities['safari:useSimulator'] !== true) {\n    return true;\n  }\n\n  return false;\n};\n\n/**\n * check if the target is a mobile platform\n * @param {Object} desiredCapabilities\n * @returns {Boolean}\n */\nfunction isMobile(desiredCapabilities){\n  if (isIos(desiredCapabilities) || isAndroid(desiredCapabilities)) {\n    return true;\n  }\n\n  return false;\n};\n\n/**\n * Check if Real iOS device UDID is correct\n * @param {String} udid\n * @returns {String}\n */\nfunction iosRealDeviceUDID(udid){\n  if (udid.length > 25) {\n    return udid;\n  }\n\n  if (udid.length < 24) {\n    throw new Error('Incorrect UDID provided for real iOS device');\n  }\n\n  return `${udid.substring(0, 8)}-${udid.substring(9, 25)}`;\n};\n\n/**\n * Function to kill iOS Simulator\n * @param {String} udid\n */\nfunction killSimulator(udid) {\n  const cmd = `xcrun simctl shutdown ${udid}`;\n\n  try {\n    execSync(cmd, {\n      stdio: 'pipe'\n    });\n  } catch (e) {\n    Logger.err(e);\n  }\n}\n\n/**\n * Function to set and return the ANDROID_HOME\n * @returns {String}\n */\nfunction getSdkRootFromEnv() {\n  const androidHome = process.env.ANDROID_HOME;\n\n  if (androidHome) {\n    return process.env.ANDROID_HOME = path.resolve(untildify(androidHome));\n  }\n\n  throw new AndroidHomeError(androidHome);\n}\n\n\nclass AndroidHomeError extends Error {\n  constructor(androidHome) {\n    super();\n\n    this.message = 'ANDROID_HOME environment variable is NOT set or is NOT a valid path!';\n    this.name = 'AndroidHomeError';\n    this.help = [\n      `To setup Android requirements, run: ${Logger.colors.cyan('npx @nightwatch/mobile-helper android')}`,\n      `For Android help, run: ${Logger.colors.cyan('npx @nightwatch/mobile-helper android --help \\n')}`\n    ];\n    this.stack = false;\n    this.androidHome = androidHome;\n  }\n}\n\nclass RealIosDeviceIdError extends Error {\n  constructor() {\n    super();\n\n    this.name = 'RealIosDeviceIdError';\n    this.message = 'Real Device ID is neither configured nor passed';\n    this.help = [\n      `Pass ${Logger.colors.green('deviceId')} in the command (for e.g : ${Logger.colors.cyan('--deviceId 00008030-00024C2C3453402E')})`,\n      `Or pass ${Logger.colors.green('safari:deviceUDID')} capability in config`,\n      `To verify the deviceId run, ${Logger.colors.cyan('system_profiler SPUSBDataType | sed -n \\'/iPhone/,/Serial/p\\' | grep \\'Serial Number:\\' | awk -F \\': \\' \\'{print $2}')}`,\n      `For more help, run: ${Logger.colors.cyan('npx @nightwatch/mobile-helper ios')}\\n`\n    ];\n    this.stack = false;\n  }\n}\n\nfunction getBinaryLocation(binaryName) {\n  const {getBinaryLocation, getPlatformName} = requireMobileHelper();\n\n  return getBinaryLocation(getSdkRootFromEnv(), getPlatformName(), binaryName, true);\n}\n\nclass AndroidBinaryError extends Error {\n  constructor(message, binaryName) {\n    super();\n\n    this.message = message;\n    this.stack = false;\n    this.binaryName = binaryName;\n  }\n\n  get help() {\n    let help;\n    const binaryLocation = getBinaryLocation(this.binaryName);\n\n    if (binaryLocation === '') {\n      help = [\n        `${Logger.colors.cyan(this.binaryName)} binary not found. Run command ${Logger.colors.cyan('npx @nightwatch/mobile-helper android')} to setup the missing requirements.`\n      ];\n    } else if (this.binaryName === 'emulator') {\n      help = [\n        `Run ${Logger.colors.cyan('npx @nightwatch/mobile-helper android')} and re-run the test.`,\n        `If it still doesn't work, start the emulator by yourself by running ${Logger.colors.cyan(binaryLocation + ' @' + this.avd)} and then run the test.`\n      ];\n    } else {\n      help = [\n        `Run ${Logger.colors.cyan('npx @nightwatch/mobile-helper android')} and re-run the test.`\n      ];\n    }\n\n    return help;\n  }\n}\n\nclass AndroidConnectionError extends Error {\n  constructor({message, detailedErr, extraDetail}) {\n    super();\n\n    this.message = message;\n    this.extraHelp = [detailedErr, extraDetail + '\\n'];\n    this.stack = false;\n  }\n\n  get help() {\n    let binaryLocation = getBinaryLocation('adb');\n    let help;\n\n    if (binaryLocation === '') {\n      help = [\n        `${Logger.colors.cyan('adb')} binary not found. Run command ${Logger.colors.cyan('npx @nightwatch/mobile-helper android')} to setup the missing requirements.`\n      ];\n    } else {\n      if (binaryLocation === 'PATH') {\n        binaryLocation = 'adb';\n      }\n\n      if (this.message.includes('Failed to run adb command')) {\n        help = [\n          `Run command: ${Logger.colors.cyan(binaryLocation + ' start-server')}`,\n          `If still doesn't work, run \"${Logger.colors.green('npx @nightwatch/mobile-helper android')}\"`\n        ];\n      }\n\n      if (this.message.includes('no devices online')) {\n        help = [\n          `If testing on real-device, check if device is connected with USB debugging turned on and ${Logger.colors.cyan(binaryLocation + ' devices')} should list the connected device.`,\n          `If testing on emulator, check the Nightwatch configuration to make sure ${Logger.colors.cyan('real_mobile')} is set to ${Logger.colors.cyan('false')} and ${Logger.colors.cyan('avd')} to the name of AVD to launch and test on.`\n        ];\n      }\n    }\n\n    return [...help, ...this.extraHelp];\n  }\n}\n\n\nclass IosSessionNotCreatedError extends Error {\n  constructor({message, name}, desiredCapabilities) {\n    super();\n\n    this.message = message;\n    this.name = name;\n    this.stack = false;\n    this.desiredCapabilities = desiredCapabilities;\n  }\n\n  get help() {\n    let help;\n\n    if (this.message.includes('session timed out')) {\n      // 'The session timed out while connecting to a Safari instance.'\n      help = [\n        'Re-run the test command',\n        `If it doesn't work, try running: ${Logger.colors.cyan('npx @nightwatch/mobile-helper ios')}`\n      ];\n    } else if (this.message.includes('not find any session hosts') || this.message.includes('Some devices were found')) {\n      // Could not find any session hosts that match the requested capabilities\n      // or some devices were found, but could not be used\n      if (isSimulator(this.desiredCapabilities)) {\n        help = [\n          `Run command to get device list: ${Logger.colors.cyan('xcrun simctl list devices')}`,\n          `Update the ${Logger.colors.cyan('safari:platformVersion')} and/or ${Logger.colors.cyan('safari:platforName')} in Nightwatch configuration accordingly`,\n          `If it doesn't work, try running: ${Logger.colors.cyan('npx @nightwatch/mobile-helper ios')}`\n        ];\n      } else {\n        help = [\n          `Make sure you have passed correct ${Logger.colors.green('deviceId')} in the command (for e.g : ${Logger.colors.cyan('--deviceId 00008030-00024C2C3453402E')})`,\n          `Or pass ${Logger.colors.green('safari:deviceUDID')} capability in config`,\n          `To verify the deviceId run, ${Logger.colors.cyan('system_profiler SPUSBDataType | sed -n \\'/iPhone/,/Serial/p\\' | grep \\'Serial Number:\\' | awk -F \\': \\' \\'{print $2}')}`,\n          `For more help, run: ${Logger.colors.cyan('npx @nightwatch/mobile-helper ios')}\\n`\n        ];\n      }\n    } else if (this.desiredCapabilities['safari:deviceUDID']) {\n      help = [\n        `Verify the UDID of the device set in Nightwatch configuration (look for ${Logger.colors.cyan('safari:deviceUDID')} capability) or pass the correct UDID using ${Logger.colors.cyan('--deviceId')} flag in the test command.`,\n        'Re-run the test command',\n        `If it doesn't work, try running: ${Logger.colors.cyan('npx @nightwatch/mobile-helper ios')}`\n      ];\n\n      if (isRealIos(this.desiredCapabilities)) {\n        help = [\n          `Check device connection by running command: ${Logger.colors.cyan('system_profiler SPUSBDataType | sed -n \\'/iPhone/,/Serial/p\\' | grep \\'Serial Number:\\' | awk -F \\': \\' \\'{print $2}')}`,\n          ...help\n        ];\n      }\n    }\n\n    return help;\n  }\n}\n\n\nmodule.exports = {\n  isMobile,\n  isIos,\n  isRealIos,\n  isSimulator,\n  isAndroid,\n  iosRealDeviceUDID,\n  killSimulator,\n  getSdkRootFromEnv,\n\n  RealIosDeviceIdError,\n  AndroidConnectionError,\n  IosSessionNotCreatedError,\n  AndroidBinaryError,\n  AndroidHomeError,\n  requireMobileHelper\n};\n"
  },
  {
    "path": "lib/utils/periodic-promise.js",
    "content": "const EventEmitter = require('events');\nconst createPromise = require('./createPromise');\n\nclass PeriodicPromise extends EventEmitter {\n  get rescheduleInterval() {\n    return this.__rescheduleIntervalMs;\n  }\n\n  get ms() {\n    return this.__timeoutMs;\n  }\n\n  get elapsedTime() {\n    return new Date().getTime() - this.startTime;\n  }\n\n  get queue() {\n    return this.__queue;\n  }\n\n  constructor({\n    rescheduleInterval,\n    timeout\n  }) {\n    super();\n\n    this.__queue = [];\n    this.__rescheduleIntervalMs = rescheduleInterval;\n    this.__timeoutMs = timeout;\n    this.retries = 0;\n  }\n\n  queueAction(opts) {\n    this.__queue.push(opts);\n\n    return this;\n  }\n\n  async runAction({prevResult, prevQueuePromise}) {\n    if (!this.queue.length) {\n      return null;\n    }\n\n    const queuePromise = this.queue.shift();\n    const deferred = createPromise();\n\n    try {\n      const result = await this.perform(queuePromise, {prevResult, prevQueuePromise}, deferred);\n\n      if (this.queue.length) {\n        return await this.runAction({\n          prevResult: result,\n          prevQueuePromise: queuePromise\n        });\n      }\n\n      return result;\n    } catch (err) {\n      if (err.name === 'TypeError' || err.name === 'ReferenceError' || !queuePromise.errorHandler) {\n        throw err;\n      }\n\n      if (queuePromise.errorHandler) {\n        return queuePromise.errorHandler(err);\n      }\n    }\n  }\n\n  async perform({\n    action,\n    validate,\n    isResultStale,\n    successHandler = (r) => Promise.resolve(r),\n    shouldRetryOnError = () => true,\n    retryOnSuccess = false,\n    retryOnFailure = true\n  }, {prevResult, prevQueuePromise}, deferred) {\n    let currentResult;\n    try {\n      // running the current action using the result from the previous action\n      currentResult = await action(prevResult);\n\n      // if the current action returns a stale reference to the previous result, re-run the previous action\n      if (isResultStale && isResultStale(currentResult)) {\n        const freshResult = await prevQueuePromise.action({cacheElementId: false});\n        if (freshResult.error instanceof Error) {\n          throw freshResult.error;\n        }\n        currentResult = await action(freshResult);\n      }\n    } catch (err) {\n      currentResult = {\n        status: -1,\n        message: err.message,\n        stack: err.stack\n      };\n    }\n\n    const isValidResult = validate(currentResult);\n\n    if (this.shouldRetry({retryOnSuccess, isValidResult, currentResult, shouldRetryOnError, retryOnFailure})) {\n      this.reschedule(arguments[0], arguments[1], deferred);\n\n      return deferred.promise;\n    }\n\n    if (isValidResult) {\n      currentResult = await successHandler(currentResult);\n      deferred.resolve(currentResult);\n\n      return deferred.promise;\n    }\n\n    throw this.getError(currentResult);\n  }\n\n  run() {\n    this.startTime = new Date().getTime();\n\n    return this.runAction({});\n  }\n\n  reschedule(promise, opts, deferred) {\n    setTimeout(() => {\n      this.retries++;\n      this.perform(promise, opts, deferred).catch(err => {\n        deferred.reject(err);\n      });\n    }, this.rescheduleInterval);\n  }\n\n  shouldRetry({retryOnFailure, retryOnSuccess, shouldRetryOnError, isValidResult, currentResult}) {\n    const now = new Date().getTime();\n    const timePassed = (now - this.startTime) >= this.ms;\n    const retryOnFailureResult = typeof retryOnFailure == 'function' ? retryOnFailure() : retryOnFailure;\n\n    if (timePassed) {\n      return false;\n    }\n\n    if (retryOnFailureResult && !isValidResult) {\n      return shouldRetryOnError(currentResult);\n    }\n\n    const needsRetryOnSuccess = typeof retryOnSuccess == 'function' ? retryOnSuccess(currentResult) : retryOnSuccess;\n\n    return (needsRetryOnSuccess && isValidResult);\n  }\n\n  getError(response) {\n    if (response instanceof Error) {\n      return response;\n    }\n\n    const {startTime, retries} = this;\n\n    let {message = 'timeout error'} = response;\n    if (response.error) {\n      message = response.error;\n      if (response.value && response.value.message) {\n        message = response.value.message;\n      } else if (message.message) {\n        message = message.message;\n      }\n    }\n\n    return new TimeoutError({\n      message,\n      now: Date.now(),\n      startTime,\n      response,\n      retries\n    });\n  }\n}\n\nclass TimeoutError extends Error {\n  constructor({message, now, response, startTime, retries}) {\n    super(message);\n\n    this.name = 'TimeoutError';\n    this.now = now;\n    this.response = response;\n    this.startTime = startTime;\n    this.retries = retries;\n  }\n}\n\nmodule.exports = PeriodicPromise;\n"
  },
  {
    "path": "lib/utils/printVersionInfo.js",
    "content": "const VERSION = require('./version');\n\nmodule.exports = function() {\n\n  // eslint-disable-next-line no-console\n  console.log('\\n  Nightwatch:');\n  // eslint-disable-next-line no-console\n  console.log('    version: ' + VERSION.full);\n  // eslint-disable-next-line no-console\n  console.log('    changelog: https://github.com/nightwatchjs/nightwatch/releases/tag/v' + VERSION.full + '\\n');\n};\n"
  },
  {
    "path": "lib/utils/requireModule.js",
    "content": "const mergeDefaultAndNamedExports = (module) => {\n  const _default = module.default || {};\n  return Object.keys(module).reduce((prev, val) => {\n    if (val !== 'default') {\n      prev[val] = module[val];\n    }\n\n    return prev;\n  }, _default);\n}\n\n/**\n * Requires a module, supporting both CommonJS and ES6 modules.\n *\n * @param {string} fullpath - The full path to the module to require.\n * @returns {any|Promise<any>} - The required module or a promise that resolves to the required module.\n */\nmodule.exports = function (fullpath) {\n  let exported;\n  try {\n    exported = require(fullpath);\n  } catch (err) {\n    const isEsmSyntaxError = err.message === 'Cannot use import statement outside a module' ||\n      err.message.includes('Unexpected token \\'export\\'');\n    const isMjsFile = fullpath.endsWith('.mjs');\n\n    // calling require() on a .mjs file on Node.js < 20 throws ERR_REQUIRE_ESM.\n    // calling require() on a .mjs file on Node.js >= 20 passes through without\n    // any error, but if ts-node is activated, it throws ERR_REQUIRE_ESM in normal\n    // cases (it still relies on the old CommonJS loader) and isEsmSyntaxError if\n    // v8-compile-cache-lib is used (see PR #4437).\n    // Use dynamic import() in both cases.\n    if (err.code === 'ERR_REQUIRE_ESM' || (isMjsFile && isEsmSyntaxError)) {\n      const { pathToFileURL } = require('node:url');\n\n      return import(pathToFileURL(fullpath).href).then(mergeDefaultAndNamedExports);\n    }\n\n    if (isEsmSyntaxError) {\n      err.detailedErr = err.message;\n      err.help = ['Using ES6 import/export syntax? - make sure to specify \"type=module\" in your package.json or use .mjs extension.'];\n      err.link = 'https://nodejs.org/api/esm.html';\n    }\n\n    throw err;\n  }\n\n  if (exported && Object.prototype.hasOwnProperty.call(exported, 'default')) {\n    const keys = Object.keys(exported);\n    if (keys.length === 1 || (keys.length === 2 && exported.__esModule === true)) {\n      return exported.default;\n    }\n  }\n\n  if (exported?.__esModule === true) {\n    // ESM module with named exports present (with or without default export).\n    return mergeDefaultAndNamedExports(exported);\n  }\n\n  return exported;\n}\n"
  },
  {
    "path": "lib/utils/safeStringify.js",
    "content": "class SafeStringify {\n  static visit(obj, seen) {\n    if (obj == null || typeof obj !== 'object') {\n      return obj;\n    }\n\n    if (seen.indexOf(obj) !== -1) {\n      return '[Circular]';\n    }\n    seen.push(obj);\n\n    if (typeof obj.toJSON === 'function') {\n      try {\n        const result = this.visit(obj.toJSON(), seen);\n        seen.pop();\n\n        return result;\n      } catch (err) {\n        return '[Error]';\n      }\n    }\n    if (Array.isArray(obj)) {\n      const result = obj.map(val => this.visit(val, seen));\n      seen.pop();\n\n      return result;\n    }\n\n    const result = Object.keys(obj).reduce((result, prop) => {\n      result[prop] = this.visit(obj[prop], seen);\n\n      return result;\n    }, {});\n    seen.pop();\n\n    return result;\n  }\n\n  static safeJSON(obj) {\n    const seen = [];\n\n    return this.visit(obj, seen);\n  }\n\n  static stringify(obj) {\n    return JSON.stringify(this.safeJSON(obj));\n  }\n}\n\nmodule.exports = SafeStringify;\n"
  },
  {
    "path": "lib/utils/screenshots.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst Defaults = require('../settings/defaults.js');\n\nclass Screenshots {\n  /**\n   * @param {object} prefix\n   * @param {object} screenshots\n   * @return {string}\n   */\n  static getFileName({testSuite, testCase, isError = false}, screenshots) {\n    const dateObject = new Date();\n    let filename;\n    let filename_format;\n\n    if (typeof screenshots.filename_format == 'function') {\n      filename_format = screenshots.filename_format.bind(screenshots);\n    } else {\n      filename_format = Defaults.screenshots.filename_format;\n    }\n\n    filename = filename_format({testSuite, testCase, isError, dateObject});\n    filename = filename.replace(/\\s/g, '-').replace(/[\"']/g, '');\n\n    return path.join(screenshots.path, filename);\n  }\n}\n\nmodule.exports = Screenshots;\n"
  },
  {
    "path": "lib/utils/seleniumAtoms.js",
    "content": "const getAttribute = 'get-attribute.js';\nconst isDisplayed = 'is-displayed.js';\nconst findElements = 'find-elements.js';\n\nconst path = require('path');\nconst SELENIUM_ATOMS_PATH = path.join(path.dirname(require.resolve('selenium-webdriver')), 'lib', 'atoms');\n\n/**\n * @param {string} module\n * @return {!Function}\n */\nfunction requireAtom(module) {\n  try {\n    return require(path.join(SELENIUM_ATOMS_PATH, module));\n  } catch (ex) {\n    throw Error(`Failed to import atoms module ${module} using Selenium path: ${SELENIUM_ATOMS_PATH}`);\n  }\n}\n\nmodule.exports = {\n  requireIsDisplayed() {\n    return requireAtom(isDisplayed);\n  }\n};\n\n"
  },
  {
    "path": "lib/utils/snapshots.js",
    "content": "const path = require('path');\nconst Defaults = require('../settings/defaults.js');\n\nclass Snapshots {\n  /**\n   * @param {object} prefix\n   * @param {object} snapshots\n   * @return {string}\n   */\n  static getFileName({testSuite, testCase, commandName, traceSettings = Defaults.trace, output_folder = ''}) {\n    const dateObject = new Date();\n    let filename_format;\n    let filename;\n\n    if (typeof traceSettings.filename_format == 'function') {\n      filename_format = traceSettings.filename_format.bind(traceSettings);\n    } else {\n      filename_format = Defaults.trace.filename_format;\n    }\n\n    const base_path = traceSettings.path || `${output_folder}/snapshots`;\n\n    filename = filename_format({testSuite, testCase, commandName, dateObject});\n    filename = filename.replace(/\\s/g, '-').replace(/[\"']/g, '');\n\n    return path.join(base_path, filename);\n  }\n}\n\nmodule.exports = Snapshots;\n"
  },
  {
    "path": "lib/utils/stackTrace.js",
    "content": "const boxen = require('boxen');\nconst {colors} = require('./chalkColors.js');\nconst isErrorObject = require('./isErrorObject');\nconst addDetailedError = require('./addDetailedError.js');\nconst indentRegex = /^/gm;\n\nconst stackTraceFilter = function (parts) {\n  const stack = parts.reduce(function(list, line) {\n    if (contains(line, [\n      'node_modules',\n      '(node.js:',\n      '(timers.js:',\n      '(events.js:',\n      '(util.js:',\n      '(net.js:',\n      '(internal/process/',\n      'internal/modules/cjs/loader.js',\n      'internal/modules/cjs/helpers.js',\n      'internal/timers.js',\n      '_http_client.js:',\n      'process._tickCallback',\n      'node:internal/'\n    ])) {\n      return list;\n    }\n\n    list.push(line);\n\n    return list;\n  }, []);\n\n  return stack.join('\\n');\n};\n\nconst contains = function(str, text) {\n  if (Array.isArray(text)) {\n    for (let i = 0; i < text.length; i++) {\n      if (contains(str, text[i])) {\n        return true;\n      }\n    }\n  }\n\n  return str.includes(text);\n};\n\nconst filterStack = function(err) {\n  if (err instanceof Error) {\n    const stackTrace = err.stack.split('\\n').slice(1);\n\n    return stackTraceFilter(stackTrace);\n  }\n\n  return '';\n};\n\nconst filterStackTrace = function(stackTrace = '') {\n  const sections = stackTrace.split('\\n');\n\n  return stackTraceFilter(sections);\n};\n\nconst showStackTrace = function (stack) {\n  const parts = stack.split('\\n');\n  const headline = parts.shift();\n\n  console.error(colors.red(headline.replace(indentRegex, '   ')));\n\n  if (parts.length > 0) {\n    const result = stackTraceFilter(parts);\n    console.error(colors.stack_trace(result.replace(indentRegex, '   ')));\n  }\n};\n\n/**\n * @method errorToStackTrace\n * @param {Error} err\n */\nconst errorToStackTrace = function(err) {\n  if (!isErrorObject(err)) {\n    err = new Error(err);\n  }\n\n  addDetailedError(err);\n\n  let headline = err.message ? `${err.name}: ${err.message}` : err.name;\n  headline = colors.red(headline.replace(indentRegex, ' '));\n\n  if (err.detailedErr) {\n    headline += `\\n ${colors.light_green(err.detailedErr)}`;\n    if (err.extraDetail) {\n      headline += `\\n ${colors.light_green(err.extraDetail)}`;\n    }\n  }\n\n  const showStack = err.showTrace || err.showTrace === undefined;\n  let stackTrace = '';\n\n  if (!showStack && err.reportShown) {\n    return ' ' + headline;\n  }\n\n  if (!showStack) {\n    return '\\n' + boxen(`${headline}\\n`, {padding: 1, borderColor: 'red'}) + '\\n';\n  }\n\n  stackTrace = filterStack(err);\n  stackTrace = '\\n' + colors.stack_trace(stackTrace.replace(indentRegex, '   '));\n\n  return `${headline}${stackTrace}`;\n};\n\nmodule.exports = {\n  errorToStackTrace,\n  stackTraceFilter,\n  filterStack,\n  filterStackTrace,\n  showStackTrace\n};\n"
  },
  {
    "path": "lib/utils/timed-callback.js",
    "content": "class TimeoutError extends Error {\n  constructor(message) {\n    super(message);\n\n    this.name = 'TimeoutError';\n  }\n}\n\nclass TimedCallback {\n\n  constructor(callbackFn, name, timeoutMs) {\n    this.callbackFn = callbackFn;\n    this.name = name;\n    this.timeoutMs = timeoutMs;\n    this.__onTimeoutExpired = null;\n    this.__onTimerStarted = null;\n  }\n\n  get onTimeoutExpired() {\n    return this.__onTimeoutExpired || function() {};\n  }\n\n  get onTimerStarted() {\n    return this.__onTimerStarted || function() {};\n  }\n\n  /**\n   * @param {function} val\n   */\n  set onTimeoutExpired(val) {\n    this.__onTimeoutExpired = val;\n  }\n\n  /**\n   * @param {function} val\n   */\n  set onTimerStarted(val) {\n    this.__onTimerStarted = val;\n  }\n\n  getWrapper() {\n    this.createTimeout();\n\n    return (err) => {\n      clearTimeout(this.timeoutId);\n      this.callbackFn(err);\n    };\n  }\n\n  createTimeout() {\n    this.timeoutId = setTimeout(() => {\n      const err = new TimeoutError(`done() callback timeout of ${this.timeoutMs}ms was reached while executing \"${this.name}\".` +\n        ' Make sure to call the done() callback when the operation finishes.');\n      this.onTimeoutExpired(err, this.name, this.timeoutMs);\n    }, this.timeoutMs);\n\n    this.onTimerStarted(this.timeoutId);\n  }\n}\n\nmodule.exports = TimedCallback;\n"
  },
  {
    "path": "lib/utils/version.js",
    "content": "const packageConfig = require(__dirname + '/../../package.json');\nconst fullVersion = packageConfig.version;\n\nmodule.exports = {\n  full: fullVersion,\n  major: fullVersion.split('.')[0],\n  minor: fullVersion.split('.')[1],\n  patch: fullVersion.split('.').slice(2).join('.')\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"nightwatch\",\n  \"description\": \"Easy to use Node.js based end-to-end testing solution for web applications using the W3C WebDriver API.\",\n  \"version\": \"3.15.0\",\n  \"author\": \"Andrei Rusu\",\n  \"homepage\": \"https://nightwatchjs.org\",\n  \"main\": \"./lib/index.js\",\n  \"types\": \"./types/index.d.ts\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/nightwatchjs/nightwatch/issues\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/nightwatchjs/nightwatch.git\"\n  },\n  \"dependencies\": {\n    \"@nightwatch/chai\": \"5.0.3\",\n    \"@nightwatch/html-reporter-template\": \"^0.3.0\",\n    \"@nightwatch/nightwatch-inspector\": \"^1.0.1\",\n    \"@types/chai\": \"^4.3.5\",\n    \"@types/selenium-webdriver\": \"^4.1.14\",\n    \"ansi-to-html\": \"0.7.2\",\n    \"aria-query\": \"5.1.3\",\n    \"assertion-error\": \"1.1.0\",\n    \"boxen\": \"5.1.2\",\n    \"chai-nightwatch\": \"^0.5.3\",\n    \"chalk\": \"^4.1.2\",\n    \"ci-info\": \"3.3.0\",\n    \"cli-table3\": \"^0.6.3\",\n    \"devtools-protocol\": \"^0.0.1140464\",\n    \"didyoumean\": \"^1.2.2\",\n    \"dotenv\": \"16.3.1\",\n    \"ejs\": \"^3.1.10\",\n    \"envinfo\": \"7.11.0\",\n    \"glob\": \"7.2.3\",\n    \"jsdom\": \"^24.1.0\",\n    \"lodash\": \"^4.17.21\",\n    \"minimatch\": \"3.1.2\",\n    \"minimist\": \"1.2.6\",\n    \"mocha\": \"10.8.2\",\n    \"nightwatch-axe-verbose\": \"^2.3.0\",\n    \"open\": \"8.4.2\",\n    \"ora\": \"5.4.1\",\n    \"piscina\": \"^4.3.1\",\n    \"selenium-webdriver\": \"4.27.0\",\n    \"semver\": \"7.5.4\",\n    \"stacktrace-parser\": \"0.1.10\",\n    \"strip-ansi\": \"6.0.1\",\n    \"untildify\": \"4.0.0\",\n    \"uuid\": \"8.3.2\"\n  },\n  \"devDependencies\": {\n    \"@cucumber/cucumber\": \"^8.2.1\",\n    \"@swc/core\": \"^1.3.67\",\n    \"@types/node\": \"^18.17.3\",\n    \"@typescript-eslint/eslint-plugin\": \"^6.3.0\",\n    \"@typescript-eslint/parser\": \"^6.3.0\",\n    \"copyfiles\": \"^2.4.1\",\n    \"cross-env\": \"^7.0.3\",\n    \"eslint\": \"^8.46.0\",\n    \"husky\": \"^8.0.0\",\n    \"is-ci\": \"^3.0.1\",\n    \"js-yaml\": \"^3.13.1\",\n    \"lint-staged\": \"^13.2.2\",\n    \"mocha-junit-reporter\": \"^2.0.2\",\n    \"mochawesome\": \"^7.1.3\",\n    \"mochawesome-merge\": \"^4.2.1\",\n    \"mochawesome-report-generator\": \"^6.2.0\",\n    \"mockery\": \"~2.1.0\",\n    \"nock\": \"^13.2.9\",\n    \"nyc\": \"^15.1.0\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\",\n    \"rimraf\": \"^3.0.2\",\n    \"serve\": \"^14.2.0\",\n    \"ts-node\": \"^10.9.1\",\n    \"tsd\": \"^0.31.2\",\n    \"wait-on\": \"^7.2.0\"\n  },\n  \"peerDependencies\": {\n    \"@cucumber/cucumber\": \"*\"\n  },\n  \"peerDependenciesMeta\": {\n    \"chromedriver\": {\n      \"optional\": true\n    },\n    \"geckodriver\": {\n      \"optional\": true\n    },\n    \"@cucumber/cucumber\": {\n      \"optional\": true\n    }\n  },\n  \"bin\": {\n    \"nightwatch\": \"./bin/nightwatch\"\n  },\n  \"man\": \"\",\n  \"scripts\": {\n    \"eslint\": \"eslint index.js lib bin api examples test --quiet\",\n    \"mocha\": \"mocha\",\n    \"mocha-coverage\": \"nyc --reporter=html mocha test/src/ --recursive\",\n    \"test\": \"mocha test/src/ --recursive --timeout 20000\",\n    \"test:types\": \"tsd --files types/tests\",\n    \"component-tests\": \"mocha test/component-tests/src\",\n    \"test-cucumber\": \"mocha test/cucumber-integration-tests --parallel\",\n    \"coverage\": \"npx nyc report --reporter=text-lcov > ./coverage/mocha_coverage.lcov\",\n    \"prepare\": \"husky install\"\n  },\n  \"eslintConfig\": {\n    \"extends\": \"eslint:recommended\",\n    \"env\": {\n      \"browser\": false,\n      \"node\": true\n    },\n    \"rules\": {\n      \"eqeqeq\": \"off\",\n      \"curly\": [\n        \"error\",\n        \"all\"\n      ],\n      \"quotes\": [\n        \"error\",\n        \"single\"\n      ]\n    }\n  },\n  \"engines\": {\n    \"node\": \">= 18.20.5\"\n  },\n  \"keywords\": [\n    \"nightwatch\",\n    \"nightwatchjs\",\n    \"selenium\",\n    \"testing\",\n    \"webdriver\",\n    \"browserstack\",\n    \"end-to-end\",\n    \"automated-testing\",\n    \"e2e\",\n    \"component\",\n    \"integration\",\n    \"test\",\n    \"browser\",\n    \"mobile\",\n    \"runner\",\n    \"appium\",\n    \"cucumber\",\n    \"mocha\",\n    \"automation\"\n  ],\n  \"files\": [\n    \"bin\",\n    \"examples\",\n    \"lib\",\n    \"api\",\n    \"types\",\n    \"README.md\",\n    \"CODE_OF_CONDUCT.md\",\n    \"LICENSE.md\",\n    \"index.js\"\n  ],\n  \"lint-staged\": {\n    \"**/*.js\": [\n      \"npx eslint --fix\"\n    ]\n  }\n}\n"
  },
  {
    "path": "test/.eslintrc",
    "content": "{\n  \"extends\": [\n    \"eslint:recommended\"\n  ],\n  \"parserOptions\": {\n    \"ecmaVersion\": 2018,\n    \"sourceType\": \"module\",\n    \"ecmaFeatures\": {\n      \"jsx\": false\n    }\n  },\n  \"env\": {\n    \"browser\": false,\n    \"mocha\": true,\n    \"node\": true,\n    \"es6\": true\n  },\n  \"rules\": {\n    \"eqeqeq\": [\"error\", \"smart\"],\n    \"no-extra-boolean-cast\": 0,\n    \"quotes\": [\"error\", \"single\"],\n    \"curly\": [\"error\", \"all\"],\n    \"no-console\": [\n      \"warn\",\n      {\n        \"allow\": [\n          \"error\"\n        ]\n      }\n    ],\n    \"no-debugger\": 1,\n    \"semi\": [\n      \"warn\",\n      \"always\",\n      {\n        \"omitLastInOneLineBlock\": true\n      }\n    ],\n    \"no-trailing-spaces\": 0,\n    \"no-else-return\": 0,\n    \"no-extra-bind\": 0,\n    \"no-empty\": 1,\n    \"no-implicit-coercion\": 0,\n    \"no-useless-call\": 0,\n    \"no-return-assign\": 0,\n    \"eol-last\": 0,\n    \"no-unused-vars\": 0,\n    \"no-extra-semi\": 0,\n    \"no-underscore-dangle\": 0,\n    \"no-lone-blocks\": 0,\n    \"array-bracket-spacing\": 1,\n    \"brace-style\": [1, \"1tbs\", {\"allowSingleLine\": true}],\n    \"comma-spacing\": 1,\n    \"comma-style\": 1,\n    \"key-spacing\": 1,\n    \"one-var\": [\"error\", \"never\"],\n    \"semi-style\": [\"warn\", \"last\"],\n    \"space-in-parens\": [\"warn\", \"never\"],\n    \"keyword-spacing\": [1, {\"before\": true, \"after\": true}],\n    \"padding-line-between-statements\": [\n      \"warn\",\n      { \"blankLine\": \"always\", \"prev\": \"*\", \"next\": \"return\" }\n    ],\n    \"indent\": [\n      \"error\",\n      2,\n      {\n        \"SwitchCase\": 1\n      }\n    ]\n  },\n  \"globals\": {\n    \"Promise\": true,\n    \"Proxy\": true,\n    \"Reflect\": true\n  }\n}\n"
  },
  {
    "path": "test/apidemos/actions-api/actionsApi.js",
    "content": "const assert = require('assert');\n\ndescribe('Actions API demo tests', function() {\n\n  before((browser) => browser.url('http://localhost'));\n  after((browser) => browser.end());\n\n  test('browser.perform() actions', async (browser) => {\n    const result = await browser.perform(function() {\n      const actions = this.actions({async: true});\n\n      return actions\n        //eslint-disable-next-line\n        .keyDown(Keys.SHIFT)\n        //eslint-disable-next-line\n        .keyUp(Keys.SHIFT);\n    });\n\n    assert.strictEqual(result, undefined);\n  });\n\n\n});"
  },
  {
    "path": "test/apidemos/actions-api/asyncActionsApi.js",
    "content": "describe('Async perform Actions API demo tests', function() { \n  test('browser.perform( async fn )', async browser => {\n    const result = await browser.perform(async function() {\n      const webelement = await element('#weblogin').findElement();\n      const actions = this.actions({async: true});\n\n      return actions.click(webelement);\n    });\n  });\n});"
  },
  {
    "path": "test/apidemos/angular-test/angularTodoListWithClassicApis.js",
    "content": "describe('angularjs homepage todo list - with classic apis', function() {\n\n  it('should add a todo using global element()', function(browser) {\n    // adding a new task to the list\n    browser\n      .navigateTo('https://angularjs.org')\n      .sendKeys('[ng-model=\"todoList.todoText\"]', 'what is nightwatch?')\n      .click('[value=\"add\"]')\n\n      // verifying if there are 3 tasks in the list\n      .expect.elements('[ng-repeat=\"todo in todoList.todos\"]').count.toEqual(3)\n\n      // verifying if the third task if the one we have just added\n      .expect.element({\n        selector: '[ng-repeat=\"todo in todoList.todos\"]',\n        index: 2\n      }).text.toEqual('what is nightwatch?')\n\n      // find our task in the list and mark it as done\n      .findElement({\n        selector: '[ng-repeat=\"todo in todoList.todos\"] input',\n        index: 2\n      }, function(inputResult) {\n        const inputElement = inputResult.value;\n        browser.click(inputElement);\n      })\n      // verify if there are 2 tasks which are marked as done in the list\n      .expect.elements('*[module=todoApp] li .done-true').count.to.equal(2);\n  });\n\n});"
  },
  {
    "path": "test/apidemos/angular-test/angularTodoListWithElementGlobal.js",
    "content": "describe('angularjs homepage todo list - with element global', function() {\n\n  // using the new element() global utility in Nightwatch 2 to init elements\n  // before tests and use them later\n  const todoElement = element('[ng-model=\"todoList.todoText\"]');\n  const addButtonEl = element('[value=\"add\"]');\n\n  it('should add a todo using global element()', function() {\n    ///////////////////////////////////////////////////\n    // browser can now also be accessed as a global   |\n    ///////////////////////////////////////////////////\n\n    // adding a new task to the list\n    browser\n      .navigateTo('http://localhost')\n      .sendKeys(todoElement, 'what is nightwatch?')\n      .click(addButtonEl);\n\n    ///////////////////////////////////////////////////\n    // global expect is equivalent to browser.expect  |\n    ///////////////////////////////////////////////////\n\n    // verifying if there are 3 tasks in the list\n    expect.elements('[ng-repeat=\"todo in todoList.todos\"]').count.to.equal(3);\n\n    // verifying if the third task if the one we have just added\n    const lastElementTask = element({\n      selector: '[ng-repeat=\"todo in todoList.todos\"]',\n      index: 2\n    });\n\n    expect(lastElementTask).text.to.equal('what is nightwatch?');\n\n    // find our task in the list and mark it as done\n    lastElementTask.findElement('input', function(inputResult) {\n      if (inputResult.error) {\n        throw inputResult.error;\n      }\n\n      const inputElement = element(inputResult.value);\n      browser.click(inputElement);\n    });\n\n    // verify if there are 2 tasks which are marked as done in the list\n    expect.elements('*[module=todoApp] li .done-true').count.to.equal(2);\n  });\n\n});"
  },
  {
    "path": "test/apidemos/angular-test/angularTodoListWithElementGlobalAndError.js",
    "content": "describe('angularjs homepage todo list - with element global and stale element error', function() {\n\n  // using the new element() global utility in Nightwatch 2 to init elements\n  // before tests and use them later\n  const todoElement = element('[ng-model=\"todoList.todoText\"]');\n\n  it('should send keys to element', function() {\n    browser.sendKeys(todoElement, 'what is nightwatch?');\n  });\n\n  it('should send keys to element again with stale element error', async function(browser) {\n    await browser.sendKeys(todoElement, 'what is nightwatch?');\n  });\n});"
  },
  {
    "path": "test/apidemos/angular-test/angularTodoListWithElementGlobalAsync.js",
    "content": "describe('angularjs homepage todo list - with element global async', function() {\n\n  // using the new element() global utility in Nightwatch 2 to init elements\n  // before tests and use them later\n  const todoElement = element('[ng-model=\"todoList.todoText\"]');\n  const addButtonEl = element('[value=\"add\"]');\n\n  it('should add a todo using global element()', async function() {\n    await browser\n      .navigateTo('https://angularjs.org')\n      .sendKeys(todoElement, 'what is nightwatch?')\n      .click(addButtonEl);\n\n    await expect.elements('[ng-repeat=\"todo in todoList.todos\"]').count.to.equal(3);\n\n    const lastElementTask = element({\n      selector: '[ng-repeat=\"todo in todoList.todos\"]',\n      index: 2\n    });\n\n    await expect(lastElementTask).text.to.equal('what is nightwatch?');\n\n    // find our task in the list and mark it as done\n    const inputElement = await lastElementTask.findElement('input');\n    await browser.click(inputElement);\n\n    // verify if there are 2 tasks which are marked as done in the list\n    expect.elements('*[module=todoApp] li .done-true').count.to.equal(2);\n  });\n\n});"
  },
  {
    "path": "test/apidemos/appium/appiumTest.js",
    "content": "const assert = require('assert');\n\ndescribe('appium api demo', function () {\n  after((app) => app.end());\n\n  const availableAppiumCommands = [\n    'startActivity',\n    'getCurrentActivity',\n    'getCurrentPackage',\n    'getOrientation',\n    'setOrientation',\n    'getGeolocation',\n    'setGeolocation',\n    'pressKeyCode',\n    'longPressKeyCode',\n    'hideKeyboard',\n    'isKeyboardShown',\n    'getContexts',\n    'getContext',\n    'setContext',\n    'resetApp'\n  ];\n\n  it('test appium available API commands', async function () {\n    // app variable is available globally\n    assert.strictEqual(app !== undefined, true);\n\n    availableAppiumCommands.forEach((command) => {\n      assert.strictEqual(typeof app.appium[command], 'function');\n    });\n  });\n\n  it('Search for Nightwatch', async function () {\n    app  // available globally\n      .waitForElementPresent({selector: 'Search Wikipedia', locateStrategy: 'accessibility id'})\n      .click('accessibility id', 'Search Wikipedia')\n      .element('class name', 'android.widget.ImageButton')\n      .sendKeys('id', 'com.app:id/search', 'Nightwatch');\n  });\n});\n"
  },
  {
    "path": "test/apidemos/cdp/registerAuth.js",
    "content": "describe('cdp tests', function() {\n  it('register basic auth', function() {\n    browser.registerBasicAuth('admin', 'admin')\n      .navigateTo('http://localhost');\n  });\n});"
  },
  {
    "path": "test/apidemos/cdp/registerAuth2.js",
    "content": "describe('cdp tests', function() {\n  it('register basic auth', function() {\n    browser.registerBasicAuth('admin', 'admin')\n      .navigateTo('http://localhost');\n  });\n});"
  },
  {
    "path": "test/apidemos/chrome/chromeTest.js",
    "content": "const assert = require('assert');\n\ndescribe('chrome api demo', function () {\n  after((browser) => browser.end());\n\n  const availableChromeCommands = [\n    'launchApp',\n    'getNetworkConditions',\n    'setNetworkConditions',\n    'sendDevToolsCommand',\n    'sendAndGetDevToolsCommand',\n    'setPermission',\n    'setDownloadPath',\n    'getCastSinks',\n    'setCastSinkToUse',\n    'startCastTabMirroring',\n    'getCastIssueMessage',\n    'stopCasting'\n  ];\n\n  it('test chrome available API commands', async function () {\n    availableChromeCommands.forEach((command) => {\n      assert.strictEqual(typeof browser.chrome[command], 'function');\n    });\n  });\n\n  it('test sample chrome CDP command', async function(browser) {\n    browser.driver.sendAndGetDevToolsCommand = function(command, args) {\n      return Promise.resolve({\n        args,\n        command\n      });\n    }\n\n    const dom = await browser.chrome.sendAndGetDevToolsCommand('DOMSnapshot.captureSnapshot', {\n      computedStyles: []\n    });\n\n    assert.deepStrictEqual(dom, {\n      command: 'DOMSnapshot.captureSnapshot',\n      args: {\n        computedStyles: []\n      }\n    });\n  })\n});\n"
  },
  {
    "path": "test/apidemos/cookies/cookieTests.js",
    "content": "const assert = require('assert');\n\ndescribe('Cookie api demo tests', function() {\n\n  before(async (browser) => {\n    await browser.url('http://localhost');\n\n    return new Promise(resolve => {\n      setTimeout(function () {\n        browser.globals.calls++;\n        resolve();\n      }, 200);\n    });\n  });\n\n  after(async (browser) => {\n    await browser.end();\n    browser.globals.calls++;\n  });\n\n  test('browser.getCookie(<name>)', async (browser) => {\n    await browser.assert.strictEqual(browser.globals.calls, 1);\n    await browser.assert.urlContains('//localhost');\n\n    const test_cookie = await browser.getCookie('test_cookie');\n    assert.deepStrictEqual(test_cookie, {\n      name: 'test_cookie',\n      value: '123456',\n      path: '/',\n      domain: 'example.org',\n      secure: false\n    });\n\n    const other_cookie = await browser.getCookie('other_cookie');\n    assert.strictEqual(other_cookie, null);\n  });\n\n  test('browser.getCookies()', async (browser) => {\n    const cookies = await browser.getCookies();\n    assert.deepStrictEqual(cookies, [\n      {\n        name: 'test_cookie',\n        value: '123456',\n        path: '/',\n        domain: 'example.org',\n        secure: false\n      }\n    ]);\n  });\n\n  test('browser.cookies.get(<name>)', async (browser) => {\n    await browser.assert.strictEqual(browser.globals.calls, 1);\n    await browser.assert.urlContains('//localhost');\n\n    const test_cookie = await browser.cookies.get('test_cookie');\n    assert.deepStrictEqual(test_cookie, {\n      name: 'test_cookie',\n      value: '123456',\n      path: '/',\n      domain: 'example.org',\n      secure: false\n    });\n\n    const other_cookie = await browser.cookies.get('other_cookie');\n    assert.strictEqual(other_cookie, null);\n  });\n\n  test('browser.cookies.getAll()', async (browser) => {\n    const cookies = await browser.cookies.getAll();\n    assert.deepStrictEqual(cookies, [\n      {\n        name: 'test_cookie',\n        value: '123456',\n        path: '/',\n        domain: 'example.org',\n        secure: false\n      }\n    ]);\n  });\n});"
  },
  {
    "path": "test/apidemos/cookies/cookieTestsWithError.js",
    "content": "const assert = require('assert');\n\ndescribe('Cookie api demo tests', function() {\n\n  before((browser) => browser.url('http://localhost'));\n  after((browser) => browser.end());\n\n  test('browser.getCookies() with network errors', async (browser) => {\n    const cookies = await browser.getCookies(res => {\n      assert.ok(res.error instanceof Error);\n      assert.strictEqual(res.error.code, 'ECONNRESET');\n      assert.strictEqual(res.error.message, 'ECONNRESET socket hang up');\n      assert.strictEqual(res.status, -1);\n      assert.strictEqual(res.value, null);\n    });\n\n    assert.strictEqual(cookies, null);\n  });\n\n  test('browser.cookies.getAll() with network errors', async (browser) => {\n    const cookies = await browser.cookies.getAll(res => {\n      assert.ok(res.error instanceof Error);\n      assert.strictEqual(res.error.code, 'ECONNRESET');\n      assert.strictEqual(res.error.message, 'ECONNRESET socket hang up');\n      assert.strictEqual(res.status, -1);\n      assert.strictEqual(res.value, null);\n    });\n\n    assert.strictEqual(cookies, null);\n  });\n\n});"
  },
  {
    "path": "test/apidemos/custom-commands/testNamespacedAliases.js",
    "content": "const assert = require('assert');\n\ndescribe('custom command using namespaced aliases', function () {\n  it('test aliases are available on requested namespace', async function() {\n    assert.strictEqual(typeof browser.customPauseWithNamespacedAlias, 'function');\n    assert.strictEqual(typeof browser.newPause, 'function');\n    assert.strictEqual(typeof browser.sampleNamespace.amazingPause, 'function');\n    assert.strictEqual(typeof browser.fantasticNamespace.subNamespace.fantasticPause, 'function');\n  });\n\n  it('test custom command with a failure', async function() {\n    browser.sampleNamespace.amazingPause('200');\n  });\n});\n"
  },
  {
    "path": "test/apidemos/custom-commands/testUsingAsyncCustomAssert.js",
    "content": "describe('custom command using assert', function () {\n  it('element visible using custom command', async function() {\n    await browser.customVisible('#weblogin');\n  });\n});"
  },
  {
    "path": "test/apidemos/custom-commands/testUsingAutoInvokeCommand.js",
    "content": "describe('Test Using ES6 Async Custom Commands', function() {\n  before(browser => {\n    browser\n      .url('http://localhost');\n  });\n\n  it('sampleTest', browser => {\n    browser.customCommandInvoke();\n    browser.end();\n  });\n});\n"
  },
  {
    "path": "test/apidemos/custom-commands/testUsingCommandReturnFn.js",
    "content": "const assert = require('assert');\n\ndescribe('Test using custom commands with returnFn', function() {\n  before(browser => {\n    browser\n      .url('http://localhost');\n  });\n\n  it('sampleTest', browser => {\n    const result = browser.customCommandReturnFn();\n    assert.deepStrictEqual(result, {status: 0});\n    browser.end();\n  });\n});\n"
  },
  {
    "path": "test/apidemos/custom-commands/testUsingCustomExecute.js",
    "content": "const assert = require('assert');\n\ndescribe('custom execute', function() {\n  it('demo test', async function(browser) {\n    await browser.pause(100)\n\n    await browser.customExecuteAsync({prop: true}, function(endTime) {\n\n    })\n\n    await browser.pause(200)\n  });\n});\n"
  },
  {
    "path": "test/apidemos/custom-commands/testUsingCustomGetEmail.js",
    "content": "const assert = require('assert');\n\ndescribe('custom execute getEmail', function() {\n  it('demo test - 1', async function(browser) {\n    const result = await browser.getEmail(1);\n    \n    assert.ok(result instanceof Object);\n    assert.deepStrictEqual(result, {\n      status: -1,\n      error: 'Email not found'\n    });\n  });\n\n  it('demo test - 2', async function(browser) {\n    const result = await browser.getEmail(2);\n    \n    assert.ok(result instanceof Object);\n    assert.strictEqual(result.status, -1);\n    assert.strictEqual(result.error.message, 'Error while running .getEmail(): Email not found');\n  });\n\n  it('demo test - 3', async function(browser) {\n    const result = await browser.getEmail(3);\n    assert.strictEqual(result.abortOnFailure, true);\n    assert.strictEqual(result.error.message, 'Error while running .getEmail(): Email not found');\n  });\n});\n"
  },
  {
    "path": "test/apidemos/custom-commands/testUsingES6AsyncCustomCommands.js",
    "content": "describe('Test Using ES6 Async Custom Commands', function() {\n  before(browser => {\n    browser\n      .url('http://localhost')\n      .waitForElementPresent('#weblogin')\n      .customFindElementsES6('#weblogin', function(elements) {\n        this.assert.ok(Array.isArray(elements));\n      });\n  });\n\n  it('sampleTest', browser => {\n    browser.end();\n  });\n});\n\n\n"
  },
  {
    "path": "test/apidemos/custom-commands-parallel/testUsingES6AsyncCustomCommands.js",
    "content": "describe('Test Using Sync Custom Command returning NightwatchAPI', function() {\n  before(browser => {\n    browser.url('http://localhost');\n  });\n\n  it('sampleTest', browser => {\n    browser\n      .otherCommand()\n      .end();\n  });\n});\n"
  },
  {
    "path": "test/apidemos/elements/elementGlobalTest.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\n\ndescribe('get text using element-global', function () {\n  const signupSection = element(by.css('#signupSection'));\n\n  after(browser => browser.end());\n\n  const availableElementCommands = [\n    'getId',\n    'findElement',\n    'findElements',\n    'click',\n    'sendKeys',\n    'getTagName',\n    'getCssValue',\n    'getAttribute',\n    'getProperty',\n    'getText',\n    'getAriaRole',\n    'getAccessibleName',\n    'getRect',\n    'isEnabled',\n    'isSelected',\n    'submit',\n    'clear',\n    'isDisplayed',\n    'takeScreenshot',\n    'getWebElement'\n  ];\n\n  test('element globals command',  async function() {\n    const weblogin = element('#weblogin');\n    const tagName = await browser.waitForElementPresent(weblogin, 100).getTagName(weblogin);\n    assert.strictEqual(tagName, 'div');\n\n    browser.assert.visible(weblogin);\n\n    await expect(weblogin).to.be.visible;\n    await expect.element('#weblogin').text.contains('sample');\n\n    const webElement = await weblogin.getWebElement();\n    assert.ok(webElement instanceof WebElement);\n\n    availableElementCommands.forEach(command => {\n      assert.strictEqual(typeof weblogin[command], 'function');\n    });\n\n    const result = await weblogin.getText();\n    assert.strictEqual(result, 'sample text');\n\n    const signupSectionId = await signupSection.getId();\n    assert.strictEqual(signupSectionId, '0');\n  });\n\n});\n"
  },
  {
    "path": "test/apidemos/elements/findElementsCustomCommand.js",
    "content": "const assert = require('assert');\n\ndescribe('find elements using es6 custom command', function () {\n  after(browser => browser.end());\n\n  test('find elements', function() {\n    browser\n      .waitForElementPresent('#weblogin', 100)\n      .es6async.customFindElementsES6('#weblogin', function(elements) {\n        assert.strictEqual(elements.length, 1);\n        assert.strictEqual(elements[0].getId(), '0');\n      })\n      .es6async.customFindElements('#weblogin', function(elements) {\n        assert.strictEqual(elements.length, 1);\n        assert.strictEqual(elements[0].getId(), '0');\n      });\n  });\n\n});\n"
  },
  {
    "path": "test/apidemos/elements/findElementsPageCommands.js",
    "content": "const assert = require('assert');\n\ndescribe('demo tests with find elements in page commands', function () {\n  after(browser => browser.end());\n\n  const pageObject = this.page.workingPageObjPlain();\n\n  it('find elements', function() {\n    pageObject\n      .navigate()\n      .waitForElementPresent('@loginAsString')\n      .customFindElements('@loginAsString', function(elements) {\n        assert.strictEqual(elements.length, 1);\n        assert.strictEqual(elements[0].getId(), '0');\n      });\n  });\n\n  it('find elements with async/await', async function() {\n    const elements = await pageObject.navigate()\n      .waitForElementPresent('@loginAsString')\n      .customFindElementsES6('@loginAsString');\n\n    assert.strictEqual(elements.length, 1);\n    assert.strictEqual(elements[0].getId(), '0');\n  });\n});\n"
  },
  {
    "path": "test/apidemos/elements/testGlobalLocateStrategy.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\n\ndescribe('element-global demo for locateStrategy', function () {\n  after(browser => browser.end());\n\n  test('to determine whether or not globally set locate-strategy is ignored',  async function() {\n    const weblogin = element('//weblogin');\n    const webElement = await weblogin.getWebElement();\n\n    assert.ok(webElement instanceof WebElement);\n    assert.strictEqual(weblogin.locateStrategy, 'use_xpath');\n    assert.strictEqual(browser.options.use_xpath, true);\n  });\n  \n});\n"
  },
  {
    "path": "test/apidemos/ensure/ensureTestError.js",
    "content": "module.exports = {\n  after: function(browser) {\n    browser.end();\n  },\n\n  'Ensure badElement test': async function (browser) {\n    browser.url('http://localhost');\n    const result = await browser.ensure.elementIsSelected('#badElement');\n  }\n};"
  },
  {
    "path": "test/apidemos/ensure/ensureTestNotSelected.js",
    "content": "module.exports = {\n  after(browser) {\n    browser.end();\n  },\n\n  before() {\n    browser.url('http://localhost');\n  },\n\n  'ensure .not.elementIsSelected': function (browser) {\n    browser.ensure.not.elementIsSelected('#weblogin');\n  }\n};\n"
  },
  {
    "path": "test/apidemos/ensure/ensureTestSelected.js",
    "content": "describe('ensureTestSelected', function() {\n  after(browser => {\n    browser.end();\n  });\n\n  it('ensure elementIsSelected', function (browser) {\n    browser\n      .url('http://localhost')\n      .ensure.elementIsSelected('#weblogin');\n  });\n\n  it('ensure elementsLocated', async function (browser) {\n    await browser\n      .url('http://localhost')\n      .ensure.elementsLocated({\n        selector: '#weblogin',\n        timeout: 100\n      });\n  });\n});\n"
  },
  {
    "path": "test/apidemos/expect-global/deepEqual.js",
    "content": "describe('expect() tests ', function () {\n  it('deepEual', function() {\n    const expectedMsg = [{a: 1, b: 4}];\n    const receivedMsg = [{b: 5}];\n\n    expect(expectedMsg).eql(receivedMsg);\n  });\n});\n"
  },
  {
    "path": "test/apidemos/expect-global/expect.js",
    "content": "describe('expect() tests ', function () {\n  const signupSection = element(by.css('#signupSection'));\n\n  after(browser => browser.end());\n\n  it('weblogin has class container ',  async function() {\n    const weblogin = element('#weblogin');\n    expect(signupSection.isSelected()).to.be.true;\n    expect(weblogin.property('className')).to.be.an('array').and.contains('container');\n  });\n\n\n\n});\n"
  },
  {
    "path": "test/apidemos/firefox/firefoxTest.js",
    "content": "const assert = require('assert');\n\ndescribe('firefox api basic test', function () {\n  after((browser) => browser.end());\n\n  const availableFirefoxCommands = ['getContext', 'setContext', 'installAddon', 'uninstallAddon'];\n\n  it('test firefox available API commands', async function () {\n    availableFirefoxCommands.forEach((command) => {\n      assert.strictEqual(typeof browser.firefox[command], 'function');\n    });\n  });\n});\n"
  },
  {
    "path": "test/apidemos/namespaced-api/namespacedApiTest.js",
    "content": "const common = require('../../common.js');\nconst {browser, appium, assert, expect, firefox, document} = common.require('index.js');\n\ndescribe('namespaced api test', function() {\n  it('browser.navigateTo', function () {\n    const result = browser.navigateTo('http://localhost');\n    assert\n      .strictEqual(typeof result.navigateTo, 'function')\n      .strictEqual(typeof result.debug, 'function')\n      .strictEqual(typeof result.appium.hideKeyboard, 'function')\n      .strictEqual(typeof result.sessionId, 'string');\n  });\n\n  it('browser.appium.setOrientation', function () {\n    const result = browser.appium.setOrientation('LANDSCAPE');\n    assert\n      .strictEqual(typeof result.navigateTo, 'function')\n      .strictEqual(typeof result.debug, 'function')\n      .strictEqual(typeof result.appium.hideKeyboard, 'function')\n      .strictEqual(typeof result.sessionId, 'string');\n  });\n\n  it('appium.setOrientation', function () {\n    const result = appium.setOrientation('LANDSCAPE');\n    assert\n      .strictEqual(typeof result.navigateTo, 'undefined')\n      .strictEqual(typeof result.debug, 'undefined')\n      .strictEqual(typeof result.hideKeyboard, 'function')\n      .strictEqual(typeof result.sessionId, 'undefined');\n  });\n\n  it('document.customExecute (namespaced alias loaded on namespaced api)', function () {\n    const result = document.customExecute('acme');\n    assert\n      .strictEqual(typeof result.navigateTo, 'undefined')\n      .strictEqual(typeof result.debug, 'undefined')\n      .strictEqual(typeof result.injectScript, 'function')\n      .strictEqual(typeof result.sessionId, 'undefined');\n  });\n\n  it('assert.titleEquals', function () {\n    const result = assert.titleEquals('Localhost');\n    result\n      .throws(() => {\n        result.navigateTo();\n      }, new Error('Unknown api method \"navigateTo\".'))\n      .throws(() => {\n        result.debug();\n      }, new Error('Unknown api method \"debug\".'))\n      .throws(() => {\n        result.sessionId();\n      }, new Error('Unknown api method \"sessionId\".'))\n      .titleEquals('Localhost');\n  });\n\n  it('assert.strictEqual', function () {\n    const result = assert.strictEqual(2, 2);\n    result\n      .throws(() => {\n        result.navigateTo();\n      }, new Error('Unknown api method \"navigateTo\".'))\n      .throws(() => {\n        result.debug();\n      }, new Error('Unknown api method \"debug\".'))\n      .throws(() => {\n        result.sessionId();\n      }, new Error('Unknown api method \"sessionId\".'))\n      .titleEquals('Localhost');\n  });\n\n  it('expect assertions', function () {\n    expect(2).to.equal(2);\n    expect.title().to.equal('Localhost');\n  });\n\n  it('firefox.getContext', function () {\n    const result = firefox.getContext();\n    assert\n      .strictEqual(typeof result.navigateTo, 'undefined')\n      .strictEqual(typeof result.debug, 'undefined')\n      .strictEqual(typeof result.hideKeyboard, 'undefined')\n      .strictEqual(typeof result.sessionId, 'undefined')\n      .strictEqual(typeof result.installAddon, 'function');\n  });\n\n  it('browser.navigateTo async', async function () {\n    const result = browser.navigateTo('http://localhost');\n    assert\n      .strictEqual(typeof result.navigateTo, 'function')\n      .strictEqual(typeof result.debug, 'function')\n      .strictEqual(typeof result.appium.hideKeyboard, 'function')\n      .strictEqual(typeof result.sessionId, 'string');\n\n    assert.strictEqual(await result, null);\n  });\n\n  it('browser.appium.setOrientation async', async function () {\n    const result = browser.appium.setOrientation('LANDSCAPE');\n    assert\n      .strictEqual(typeof result.navigateTo, 'function')\n      .strictEqual(typeof result.debug, 'function')\n      .strictEqual(typeof result.appium.hideKeyboard, 'function')\n      .strictEqual(typeof result.sessionId, 'string');\n\n    assert.strictEqual(await result, null);\n  });\n\n  it('appium.setOrientation async', async function () {\n    const result = appium.setOrientation('LANDSCAPE');\n    assert\n      .strictEqual(typeof result.navigateTo, 'undefined')\n      .strictEqual(typeof result.debug, 'undefined')\n      .strictEqual(typeof result.hideKeyboard, 'function')\n      .strictEqual(typeof result.sessionId, 'undefined');\n\n    assert.strictEqual(await result, null);\n  });\n\n  it('assert.titleEquals async', async function () {\n    const result = assert.titleEquals('Localhost');\n    result\n      .strictEqual(typeof result.navigateTo, 'undefined')\n      .strictEqual(typeof result.debug, 'undefined')\n      .strictEqual(typeof result.hideKeyboard, 'undefined')\n      .strictEqual(typeof result.sessionId, 'undefined')\n      .titleEquals('Localhost')\n      .strictEqual(await result, 'Localhost');\n  });\n\n  it('assert.strictEqual async', async function () {\n    const result = assert.strictEqual(2, 2);\n    result\n      .strictEqual(typeof result.navigateTo, 'undefined')\n      .strictEqual(typeof result.debug, 'undefined')\n      .strictEqual(typeof result.hideKeyboard, 'undefined')\n      .strictEqual(typeof result.sessionId, 'undefined')\n      .titleEquals('Localhost')\n      .deepStrictEqual(await result, {returned: 1, value: null});\n  });\n});\n"
  },
  {
    "path": "test/apidemos/navigation/navigateTest.js",
    "content": "const assert = require('assert');\n\ndescribe('navigate test', function() {\n\n  after(browser => {\n    assert.strictEqual(browser.globals.calls, 5);\n\n    browser.customQuit(result => {\n      browser.globals.calls++;\n      assert.strictEqual(result.client.sessionId, null);\n    }, function() {\n      browser.globals.calls++;\n    });\n  });\n\n  it('navigateTo', function (browser) {\n    browser.navigateTo('http://localhost').perform(function() {\n      this.globals.calls++;\n    });\n  });\n\n  it('navigateTo async', async function (browser) {\n    const result = await browser.navigateTo('http://localhost', function() {\n      browser.globals.calls++;\n\n      return {status: 'success'};\n    });\n\n    assert.deepStrictEqual(result, {status: 'success'});\n\n    const url = await browser.getCurrentUrl();\n    assert.strictEqual(url, 'http://localhost');\n\n    const urlWithCallback = await browser.getCurrentUrl(function(result) {\n      browser.globals.calls++;\n\n      return result.value;\n    });\n    assert.strictEqual(urlWithCallback, 'http://localhost');\n  });\n\n});\n"
  },
  {
    "path": "test/apidemos/page-objects/commandsReturnTypeTest.js",
    "content": "const assert = require('assert');\n\ndescribe('test return type of various commands on page-objects', function () {\n  after(browser => browser.end());\n\n  const pageObject = this.page.simplePageObj();\n\n  it('return correct type on page objects in non-async mode', function() {\n    const pageClick = pageObject.click('@loginCss');\n    // pageClick does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof pageClick.submit, 'undefined');\n    assert.strictEqual(typeof pageClick.isChrome, 'undefined');\n    // pageClick has page specific methods/properties\n    assert.strictEqual(typeof pageClick.api, 'object');\n    assert.strictEqual(typeof pageClick.testCommand, 'function');\n\n    const pageAssert = pageObject.assert.visible('@loginCss');\n    // pageAssert does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof pageAssert.submit, 'undefined');\n    assert.strictEqual(typeof pageAssert.isChrome, 'undefined');\n    // pageAssert has page specific methods/properties\n    assert.strictEqual(typeof pageAssert.api, 'object');\n    assert.strictEqual(typeof pageAssert.testCommand, 'function');\n\n    const pageNodeAssert = pageObject.assert.equal(1, 1);\n    // pageNodeAssert does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof pageNodeAssert.submit, 'undefined');\n    assert.strictEqual(typeof pageNodeAssert.isChrome, 'undefined');\n    // pageNodeAssert has page specific methods/properties\n    assert.strictEqual(typeof pageNodeAssert.api, 'object');\n    assert.strictEqual(typeof pageNodeAssert.testCommand, 'function');\n\n    const pageCustomCommand = pageObject.testCommand();\n    // pageCustomCommand does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof pageCustomCommand.submit, 'undefined');\n    assert.strictEqual(typeof pageCustomCommand.isChrome, 'undefined');\n    // pageCustomCommand has page specific methods/properties\n    assert.strictEqual(typeof pageCustomCommand.api, 'object');\n    assert.strictEqual(typeof pageCustomCommand.testCommand, 'function');\n\n    const pageChaiAssert = pageObject.expect.element('@loginCss').to.be.visible;\n    // pageChaiAssert does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof pageChaiAssert.submit, 'undefined');\n    assert.strictEqual(typeof pageChaiAssert.isChrome, 'undefined');\n    // pageChaiAssert *does not* have page specific methods/properties\n    assert.strictEqual(typeof pageChaiAssert.api, 'undefined');\n    assert.strictEqual(typeof pageChaiAssert.testCommand, 'undefined');\n    // pageChaiAssert only have page Expect property/methods\n    assert.strictEqual(typeof pageChaiAssert.a, 'function');\n    assert.strictEqual(typeof pageChaiAssert.present, 'object');\n  });\n\n  it('return correct type on page objects in async mode', async function() {\n    const pageClick = pageObject.click('@loginCss');\n    assert.strictEqual(pageClick instanceof Promise, true);\n    // pageClick does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof pageClick.submit, 'undefined');\n    assert.strictEqual(typeof pageClick.isChrome, 'undefined');\n    // pageClick has page specific methods/properties\n    assert.strictEqual(typeof pageClick.api, 'object');\n    assert.strictEqual(typeof pageClick.testCommand, 'function');\n\n    const pageAssert = pageObject.assert.visible('@loginCss');\n    assert.strictEqual(pageAssert instanceof Promise, true);\n    // pageAssert does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof pageAssert.submit, 'undefined');\n    assert.strictEqual(typeof pageAssert.isChrome, 'undefined');\n    // pageAssert has page specific methods/properties\n    assert.strictEqual(typeof pageAssert.api, 'object');\n    assert.strictEqual(typeof pageAssert.testCommand, 'function');\n\n    const pageNodeAssert = pageObject.assert.equal(1, 1);\n    assert.strictEqual(pageNodeAssert instanceof Promise, true);\n    // pageNodeAssert does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof pageNodeAssert.submit, 'undefined');\n    assert.strictEqual(typeof pageNodeAssert.isChrome, 'undefined');\n    // pageNodeAssert has page specific methods/properties\n    assert.strictEqual(typeof pageNodeAssert.api, 'object');\n    assert.strictEqual(typeof pageNodeAssert.testCommand, 'function');\n\n    const pageCustomCommand = pageObject.testCommand();\n    assert.strictEqual(pageCustomCommand instanceof Promise, false);\n    // pageCustomCommand does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof pageCustomCommand.submit, 'undefined');\n    assert.strictEqual(typeof pageCustomCommand.isChrome, 'undefined');\n    // pageCustomCommand has page specific methods/properties\n    assert.strictEqual(typeof pageCustomCommand.api, 'object');\n    assert.strictEqual(typeof pageCustomCommand.testCommand, 'function');\n\n    const pageChaiAssert = pageObject.expect.element('@loginCss').to.be.visible;\n    assert.strictEqual(pageChaiAssert instanceof Promise, true);\n    // pageChaiAssert does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof pageChaiAssert.submit, 'undefined');\n    assert.strictEqual(typeof pageChaiAssert.isChrome, 'undefined');\n    // pageChaiAssert *does not* have page specific methods/properties\n    assert.strictEqual(typeof pageChaiAssert.api, 'undefined');\n    assert.strictEqual(typeof pageChaiAssert.testCommand, 'undefined');\n    // pageChaiAssert only have page Expect property/methods\n    assert.strictEqual(typeof pageChaiAssert.a, 'function');\n    assert.strictEqual(typeof pageChaiAssert.present, 'object');\n  });\n\n  it('return correct type on sections in non-async mode', function() {\n    const signUpSection = pageObject.section.signUp;\n\n    const sectionClick = signUpSection.click('@help');\n    // sectionClick does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof sectionClick.submit, 'undefined');\n    assert.strictEqual(typeof sectionClick.isChrome, 'undefined');\n    // sectionClick does not page specific methods/properties\n    assert.strictEqual(typeof sectionClick.testCommand, 'undefined');\n    // sectionClick have section specific property/methods\n    assert.strictEqual(typeof sectionClick.sectionElements, 'function');\n    assert.strictEqual(typeof sectionClick.section, 'object');\n  });\n\n  it('return correct type on sections in async mode', async function() {\n    const signUpSection = pageObject.section.signUp;\n\n    const sectionClick = signUpSection.click('@help');\n    assert.strictEqual(sectionClick instanceof Promise, true);\n    // sectionClick does not have methods specific to NightwatchAPI\n    assert.strictEqual(typeof sectionClick.submit, 'undefined');\n    assert.strictEqual(typeof sectionClick.isChrome, 'undefined');\n    // sectionClick does not page specific methods/properties\n    assert.strictEqual(typeof sectionClick.testCommand, 'undefined');\n    // sectionClick have section specific property/methods\n    assert.strictEqual(typeof sectionClick.sectionElements, 'function');\n    assert.strictEqual(typeof sectionClick.section, 'object');\n  });\n});\n"
  },
  {
    "path": "test/apidemos/relative-locators/sample-with-relative-locators.js",
    "content": "/* eslint-disable no-undef */\ndescribe('sample with relative locators', function () {\n  it('locate password input', function (browser) {\n    const passwordElement = locateWith(By.tagName('input')).below(By.css('input[type=email]'));\n\n    browser\n      .waitForElementVisible(passwordElement)\n      .expect.element(passwordElement).to.be.an('input');\n\n    browser.setValue(passwordElement, 'password');\n  });\n});"
  },
  {
    "path": "test/apidemos/web-elements/assertionTest.js",
    "content": "describe('element assertion test', function() {\n  it('element is visible', function({element}) {\n    element.find('#weblogin').assert.visible();\n    element.find('#weblogin').assert.enabled();\n  });\n\n  it('element is not visible - failure', function({element}) {\n    element.find('#weblogin').assert.not.visible();\n  });\n\n  it('element is present', function({element}){\n    element.find('#weblogin').assert.present();\n  });\n\n});"
  },
  {
    "path": "test/apidemos/web-elements/elementApiWithPageObjects.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\n\ndescribe('demo tests with new element api in page objects', function () {\n  after(browser => browser.end());\n\n  const pageObject = this.page.simplePageObj();\n\n  it('element api on page objects', async function() {\n    const elementResult = await pageObject.element('@loginAsString');\n    assert.strictEqual(elementResult instanceof WebElement, true);\n    assert.strictEqual(await elementResult.getId(), '5cc459b8-36a8-3042-8b4a-258883ea642b');\n\n    const elementFindResult = await pageObject.element.find('@loginIndexed');\n    assert.strictEqual(elementFindResult instanceof WebElement, true);\n    assert.strictEqual(await elementFindResult.getId(), '3783b042-7001-0740-a2c0-afdaac732e9f');\n\n    const elementFindAllResult = await pageObject.element.findAll('@loginXpath');\n    assert.strictEqual(elementFindAllResult.length, 2);\n    assert.strictEqual(elementFindAllResult[0] instanceof WebElement, true);\n    assert.strictEqual(await elementFindAllResult[1].getId(), '3783b042-7001-0740-a2c0-afdaac732e9f');\n\n    const findByTextResult = await pageObject.element.findByText('Web Login');\n    assert.strictEqual(findByTextResult instanceof WebElement, true);\n    assert.strictEqual(await findByTextResult.getId(), '5cc459b8-36a8-3042-8b4a-258883ea642b');\n  });\n\n  it('element api on sections', async function() {\n    const signupSection = pageObject.section.signUp;\n\n    const elementResult = await signupSection.element('@help');\n    assert.strictEqual(elementResult instanceof WebElement, true);\n    assert.strictEqual(await elementResult.getId(), '1');\n\n    const elementFindResult = await signupSection.element.find('@help');\n    assert.strictEqual(elementFindResult instanceof WebElement, true);\n    assert.strictEqual(await elementFindResult.getId(), '1');\n\n    const findByTextResult = await signupSection.element.findByText('Help');\n    assert.strictEqual(findByTextResult instanceof WebElement, true);\n    assert.strictEqual(await findByTextResult.getId(), '2');\n\n    const getStartedSection = signupSection.section.getStarted;\n\n    const elementFindResult2 = await getStartedSection.element.find('#getStartedStart');\n    assert.strictEqual(elementFindResult2 instanceof WebElement, true);\n    assert.strictEqual(await elementFindResult2.getId(), '4');\n\n    const elementFindAllResult = await getStartedSection.element.findAll('@start');\n    assert.strictEqual(elementFindAllResult.length, 3);\n    assert.strictEqual(elementFindAllResult[0] instanceof WebElement, true);\n    assert.strictEqual(await elementFindAllResult[2].getId(), '6');\n  });\n});\n"
  },
  {
    "path": "test/apidemos/web-elements/waitUntilElementNotPresent.js",
    "content": "describe('demo of failure of waitUntil element commands', function() {\n  it('waitUntil element is visible - element not present', function({element}) {\n    element.find('#badElement').waitUntil('visible');\n  });\n});"
  },
  {
    "path": "test/apidemos/web-elements/waitUntilFailureTest.js",
    "content": "describe('demo of failure of waitUntil element commands', function() {\n  it('waitUntil element is visible and but not selected', function({element}) {\n    element.find('#weblogin').waitUntil('visible').waitUntil('not.selected');\n  });\n});"
  },
  {
    "path": "test/apidemos/web-elements/waitUntilTest.js",
    "content": "describe('demo tests using waitUntil element APIs', function() {\n  it('wait until element is visible', function({element}) {\n    element('#weblogin').waitUntil('visible');\n  });\n\n  it('wait until element is selected', function({element, state}) {\n    element('#weblogin').waitUntil('present').waitUntil('selected');\n  });\n\n  it('wait until element is enabled', function({element}) {\n    element('#weblogin').waitUntil('enabled');\n  });\n\n  it('wait until with custom message', function({element}) {\n    element('#weblogin').waitUntil('enabled', {message: 'elemento %s no era presente en %d ms'});\n  });\n});\n\n"
  },
  {
    "path": "test/asynchookstests/afterEach-timeout/sampleAsyncHooks.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  afterEach: function(client, done) {\n\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/after.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  after: function(client, done) {\n    done(new Error('Provided error after'));\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/afterAsync.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  after: function(client, done) {\n    setTimeout(function() {\n      done(new Error('Provided error afterAsync'));\n    }, 10);\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/afterEach.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  afterEach: function(client, done) {\n    done(new Error('Provided error afterEach'));\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/afterEachAsync.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  afterEach: function(client, done) {\n    setTimeout(function() {\n      done(new Error('Provided error afterEachAsync'));\n    }, 10);\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/afterEachWithClient.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  afterEach: function(client, done) {\n    client.end(function() {\n      done(new Error('Provided error afterEachWithClient'));\n    });\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/afterWithClient.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  after: function(client, done) {\n    client.end(function() {\n      done(new Error('Provided error afterWithClient'));\n    });\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/before.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client\n      .url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  before: function(client, done) {\n    done(new Error('Provided error before'));\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/beforeAsync.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  before: function(client, done) {\n    setTimeout(function() {\n      done(new Error('Provided error beforeAsync'));\n    }, 10);\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/beforeEach.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  beforeEach: function(client, done) {\n    done(new Error('Provided error beforeEach'));\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/beforeEachAsync.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  beforeEach: function(client, done) {\n    setTimeout(function() {\n      done(new Error('Provided error beforeEachAsync'));\n    }, 10);\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/beforeEachAsyncWithClient.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  beforeEach: function(client, done) {\n    client.perform(function() {\n      setTimeout(function() {\n        done(new Error('Provided error beforeEachAsyncWithClient'));\n      }, 10);\n    });\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/beforeEachAsyncWithClientMultiple.js",
    "content": "var c = 0;\nmodule.exports = {\n  demoTest1: function (client) {\n    client.url('http://localhost');\n  },\n\n  demoTest2: function (client) {\n    client\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  beforeEach: function(client, done) {\n    c++;\n\n    if (c === 1) {\n      return done();\n    }\n\n    client.perform(function() {\n      setTimeout(function() {\n        done(new Error('Provided error beforeEachAsyncWithClientMultiple'));\n      }, 10);\n    });\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/beforeEachWithClient.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  beforeEach: function(client, done) {\n    client.perform(function() {\n      done(new Error('Provided error beforeEachWithClient'));\n    });\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/async-provide-error/beforeWithClient.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  before: function(client, done) {\n    client.perform(function() {\n      done(new Error('Provided error beforeWithClient'));\n    });\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/before-timeout/sampleAsyncHooks.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  before: function(client, done) {\n\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/sampleWithAssertionFailedInAfter.js",
    "content": "module.exports = {\n  before(client) {\n    client.url('http://localhost').perform(function() {\n      client.globals.calls++;\n    });\n  },\n\n  demoTestAsyncOne: function (client) {\n    client.url('http://localhost');\n  },\n\n  after(client) {\n    client.assert.equal(0, 1);\n    client.end();\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/sampleWithAssertionFailedInBefore.js",
    "content": "describe('sampleWithAssertionFailedInBefore', function() {\n  before(function(c) {\n    c.url('http://localhost');\n    c.assert.equal(0, 1);\n  });\n\n  test('demo test async', c => {\n    c.url('http://localhost');\n  });\n\n});\n"
  },
  {
    "path": "test/asynchookstests/sampleWithErrorInTestcaseAndAfter.js",
    "content": "describe('sampleWithFailureInTestcaseAndAfter', function() {\n  before(function(c) {\n    c.url('http://localhost');\n  });\n\n  test('demo test async', c => {\n    c.url('http://localhost');\n\n    throw new Error('error in testcase');\n  });\n\n  after(function(c) {\n    c.assert.strictEqual(0, 1);\n  });\n\n});\n"
  },
  {
    "path": "test/asynchookstests/sampleWithFailureInBeforeAndAfter.js",
    "content": "describe('sampleWithAssertionFailedInBefore', function() {\n  before(function(c) {\n    c.url('http://localhost');\n    c.assert.equal(0, 1);\n  });\n\n  test('demo test async', c => {\n    c.url('http://localhost');\n  });\n\n  after(function(c) {\n    c.assert.strictEqual(0, 1);\n  });\n});\n"
  },
  {
    "path": "test/asynchookstests/sampleWithFailureInTestcaseAndAfter.js",
    "content": "describe('sampleWithFailureInTestcaseAndAfter', function() {\n  before(function(c) {\n    c.url('http://localhost');\n  });\n\n  test('demo test async', c => {\n    c.url('http://localhost');\n    c.assert.equal(0, 1);\n  });\n\n  after(function(c) {\n    c.assert.strictEqual(0, 1);\n  });\n\n});\n"
  },
  {
    "path": "test/asynchookstests/unittest-async-timeout.js",
    "content": "\nmodule.exports = {\n  demoTest: function (done) {\n\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/unittest-error.js",
    "content": "module.exports = {\n  '@unitTest': true,\n  client: {},\n  demoSync() {\n\n  }\n};\n"
  },
  {
    "path": "test/asynchookstests/unittest-failure/unittest-failure.js",
    "content": "var assert = require('assert');\n\nmodule.exports = {\n  demoTest: function (done) {\n    assert.strictEqual(1, 0);\n  }\n};\n"
  },
  {
    "path": "test/common.js",
    "content": "const BASE_PATH = process.env.NIGHTWATCH_COV ? 'lib-cov' : 'lib';\nconst path = require('path');\n\nmodule.exports = {\n  require(relativeFilePath) {\n    try {\n      return require(path.join('../', BASE_PATH, relativeFilePath));\n    } catch (err) {\n      console.error('Error', err);\n      throw err;\n    }\n\n  },\n\n  requireApi(relativeFilePath) {\n    return require(path.join('../api', relativeFilePath));\n  },\n\n  resolve(relativeFilePath) {\n    return path.join('../', BASE_PATH, relativeFilePath);\n  },\n\n  requireMock(relativeFilePath, ...args) {\n    const mockedModule = require(path.join(__dirname, './lib/mocks', relativeFilePath));\n\n    return mockedModule(...args);\n  },\n\n  settings(settings) {\n    return Object.assign({\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost',\n      persist_globals: true,\n      output_folder: false,\n      output: false,\n      silent: false\n    }, settings);\n  }\n};\n\n// process.on('unhandledRejection', err => {\n//   console.error('TEST unhandledRejection:')\n//   console.error(err.stack);\n// });\n"
  },
  {
    "path": "test/component-tests/samples/nightwatch.conf-noplugins.js",
    "content": "module.exports = {\n  src_folders: [],\n  page_objects_path: [],\n  custom_commands_path: [],\n  custom_assertions_path: '',\n  globals: {},\n  webdriver: {},\n\n  test_settings: {\n    default: {\n      launch_url: 'http://localhost:3001',\n      persist_globals: true,\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {\n          w3c: true,\n          args: []\n        }\n      },\n\n      webdriver: {\n        start_process: true,\n        server_path: require('chromedriver').path,\n        cli_args: []\n      }\n    }\n  }\n};"
  },
  {
    "path": "test/component-tests/samples/react/nightwatch.conf.js",
    "content": "module.exports = {\n  src_folders: ['test/src'],\n  page_objects_path: [],\n  custom_commands_path: [],\n  custom_assertions_path: '',\n  globals: {},\n  plugins: ['@nightwatch/react'],\n  webdriver: {},\n\n  test_settings: {\n    default: {\n      disable_error_log: false,\n      launch_url: 'http://localhost:3001',\n      persist_globals: true,\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {\n          w3c: true,\n          args: [\n          ]\n        }\n      },\n\n      webdriver: {\n        start_process: true,\n        server_path: require('chromedriver').path,\n        cli_args: [\n        ]\n      }\n    }\n  }\n};"
  },
  {
    "path": "test/component-tests/samples/react/src/Form.jsx",
    "content": "import React from 'react';\n\nclass Form extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {name: ''};\n  }\n\n  handleSubmit = (e) => {\n    e.preventDefault();\n    if (!this.state.name.trim()) {\n      return;\n    }\n\n    this.setState({name: ''});\n  };\n\n  handleChange = (e) => {\n    this.setState({name: e.target.value});\n  };\n\n  render() {\n    return (\n      <form onSubmit={this.handleSubmit} method='post'>\n        <h2 className='label-wrapper'>\n          <label htmlFor='new-todo-input' className='label__lg'>\n            What needs to be done?\n          </label>\n        </h2>\n\n        <input\n          type='text'\n          id='new-todo-input'\n          data-testid=\"new-todo-input\"\n          className='input input__lg'\n          name='text'\n          autoComplete='off'\n          value={this.state.name}\n          onChange={this.handleChange}\n        />\n        <button type='submit' className='btn btn__primary btn__lg'>\n          Add\n        </button>\n      </form>\n    );\n  }\n}\n\nexport default Form;"
  },
  {
    "path": "test/component-tests/samples/react/tests/Form.spec--_with-$hooks.jsx",
    "content": "// DO NOT rename the file\nimport { fireEvent, within } from '@testing-library/dom';\nimport Form from '../src/Form.jsx';\n\nexport default {\n  title: 'Form',\n  component: Form,\n}\n\nexport const FormStory = () => <Form />\n\nexport const AnotherForm = Object.assign(() => <Form />, {\n  async beforeMount() {\n    await new Promise((resolve, reject) => setTimeout(function() {\n      resolve()\n    }, 50));\n  },\n\n  async afterMount() {\n    await new Promise((resolve, reject) => setTimeout(function() {\n      resolve()\n      //reject(new Error('something failed in after mount'));\n    }, 100));\n  },\n\n  async play({canvasElement, args}) {\n    const async_value = await new Promise((resolve) => setTimeout(function() {\n      resolve('test_value_async');\n    }, 100));\n\n    const root = within(canvasElement);\n    const input = root.getByTestId('new-todo-input');\n\n    fireEvent.change(input, {\n      target: {\n        value: 'I entered the value'\n      }\n    });\n\n    return {\n      component_element: window['@component_element'],\n      fromPlay: input,\n      async_value\n    }\n  },\n  test: async (browser, {component, result}) => {\n    await browser.assert.deepEqual(Object.keys(result), ['async_value', 'component_element', 'fromPlay']);\n    await browser.assert.strictEqual(result.async_value, 'test_value_async');\n    await browser.assert.ok('driver_' in result.fromPlay);\n    await expect(component).to.be.visible;\n    await expect(component.find('input')).to.have.property('value').equal('I entered the value');\n  }\n});"
  },
  {
    "path": "test/component-tests/samples/react/tests/formTest--notFound.js",
    "content": "describe('Render React Component test', function() {\n  let formComponent;\n\n  it('checks the react component', async function(browser) {\n    formComponent = await browser.mountComponent('/test/components/Form.jsx', {});\n    await browser.expect.element(formComponent).to.be.visible;\n  });\n});"
  },
  {
    "path": "test/component-tests/samples/react/tests/formTest.js",
    "content": "describe('Render React Component test', function() {\n  let formComponent;\n\n  it('checks the react component', async function(browser) {\n    formComponent = await browser.mountComponent('/test/component-tests/samples/react/src/Form.jsx', {});\n    await browser.expect.element(formComponent).to.be.visible;\n  });\n\n});"
  },
  {
    "path": "test/component-tests/samples/vue/nightwatch.conf.js",
    "content": "module.exports = {\n  src_folders: [],\n  page_objects_path: [],\n  custom_commands_path: [],\n  custom_assertions_path: '',\n  globals: {},\n  plugins: ['@nightwatch/vue'],\n  webdriver: {},\n  test_settings: {\n    default: {\n      disable_error_log: false,\n      launch_url: 'http://localhost:3001',\n      persist_globals: true,\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {\n          w3c: true,\n          args: [\n\n          ]\n        }\n      },\n\n      webdriver: {\n        start_process: true,\n        server_path: require('chromedriver').path,\n        cli_args: [\n        ]\n      }\n    }\n  }\n};"
  },
  {
    "path": "test/component-tests/samples/vue/src/Form.vue",
    "content": "<template>\n  <h1>Movie Review</h1>\n  <form @submit.prevent=\"submit\">\n    <label for=\"movie-input\">Title of the movie</label>\n    <input id=\"movie-input\" v-model=\"title\" name=\"title\" />\n\n    <label id=\"review-textarea\">Your review</label>\n    <textarea\n        v-model=\"review\"\n        name=\"review-textarea\"\n        placeholder=\"Write an awesome review\"\n        aria-labelledby=\"review-textarea\"\n    />\n\n    <label>\n      <input v-model=\"rating\" type=\"radio\" value=\"3\" />\n      Wonderful\n    </label>\n    <label>\n      <input v-model=\"rating\" type=\"radio\" value=\"2\" />\n      Average\n    </label>\n    <label>\n      <input v-model=\"rating\" type=\"radio\" value=\"1\" />\n      Awful\n    </label>\n\n    <label id=\"recommend-label\" for=\"recommend\">\n      Would you recommend this movie?\n    </label>\n    <input\n        id=\"recommend\"\n        v-model=\"recommend\"\n        type=\"checkbox\"\n        name=\"recommend\"\n    />\n\n    <button :disabled=\"submitDisabled\" type=\"submit\">Submit</button>\n  </form>\n</template>\n\n<script>\nexport default {\n  emits: {submit: null},\n  data() {\n    return {\n      title: '',\n      review: '',\n      rating: '1',\n      recommend: false,\n    }\n  },\n  computed: {\n    submitDisabled() {\n      return !this.title || !this.review\n    },\n  },\n  methods: {\n    submit() {\n      if (this.submitDisabled) return\n      this.$emit('submit', {\n        title: this.title,\n        review: this.review,\n        rating: this.rating,\n        recommend: this.recommend,\n      })\n    },\n  },\n}\n</script>"
  },
  {
    "path": "test/component-tests/samples/vue/tests/formTest--notFound.js",
    "content": "describe('Render Vue Component test', function() {\n  let formComponent;\n\n  it('checks the vue component', async function(browser) {\n    formComponent = await browser.mountComponent('/test/components/Form.vue', {});\n    await browser.expect.element(formComponent).to.be.visible;\n  });\n});"
  },
  {
    "path": "test/component-tests/samples/vue/tests/formTest.js",
    "content": "describe('form test', function() {\n  let component;\n\n  before(async () => {\n    component = await browser.mountComponent('/test/component-tests/samples/vue/src/Form.vue');\n  });\n\n  it('should render a form component without error', async function() {\n    await browser.expect(component).to.be.visible;\n  });\n});"
  },
  {
    "path": "test/component-tests/src/testRunBasicReact.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst {runTests} = common.require('index.js');\n\ndescribe('Component Testing -- React basic component mount tests', function() {\n  it('run a single component test without proper config', function() {\n    const testsPath = path.join(__dirname, '../samples/react/tests/formTest.js');\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 100,\n      retryAssertionTimeout: 150,\n\n      reporter(results) {\n        assert.ok(results.lastError instanceof TypeError);\n        assert.strictEqual(results.lastError.link, 'https://nightwatchjs.org/guide/concepts/component-testing.html');\n        assert.strictEqual(results.lastError.detailedErr, '  - writing a component test? - make sure to install the necessary plugins (e.g. @nightwatch/react or @nightwatch/vue)');\n      }\n    };\n\n    return runTests({\n      source: testsPath,\n      headless: true,\n      config: path.join(__dirname, '../samples/nightwatch.conf-noplugins.js')\n    }, {\n      globals,\n      output: false,\n      silent: false,\n      disable_colors: false\n    });\n  });\n\n  xit('run a single React component test with missing component', function() {\n    this.timeout(10000);\n\n    const testsPath = path.join(__dirname, '../samples/react/tests/formTest--notFound.js');\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 100,\n      retryAssertionTimeout: 150,\n\n      reporter(results) {\n        assert.strictEqual(results.errors, 1);\n        assert.strictEqual(results.failed, 0);\n        assert.strictEqual(results.passed, 0);\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.lastError.name, 'NightwatchMountError');\n        assert.strictEqual(results.lastError.message, 'time out reached (200ms) while waiting for component to mount.');\n        assert.deepStrictEqual(results.lastError.help, [\n          'run nightwatch with --devtools and --debug flags (Chrome only)',\n          'investigate the error in the browser console'\n        ]);\n      }\n    };\n\n    return runTests({\n      source: testsPath,\n      headless: true,\n      config: path.join(__dirname, '../samples/react/nightwatch.conf.js')\n    }, {\n      globals,\n      output: false,\n      silent: true,\n      disable_colors: false,\n      '@nightwatch/react': {\n        hooksRetryTimeout: 200,\n        hooksRetryInterval: 50\n      }\n    });\n  });\n\n  it('run a single React component test', function() {\n    this.timeout(100000);\n\n    const testsPath = path.join(__dirname, '../samples/react/tests/formTest.js');\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 100,\n      retryAssertionTimeout: 150,\n\n      reporter(results) {\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(results.failed, 0);\n        assert.strictEqual(results.passed, 1);\n      }\n    };\n\n    return runTests({\n      source: testsPath,\n      headless: true,\n      debug: false,\n      devtools: true,\n      config: path.join(__dirname, '../samples/react/nightwatch.conf.js')\n    }, {\n      globals,\n      output: false,\n      silent: false,\n      disable_colors: false,\n      '@nightwatch/react': {\n        hooksRetryTimeout: 1000,\n        hooksRetryInterval: 100\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/component-tests/src/testRunBasicVue.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst {runTests} = common.require('index.js');\n\ndescribe('Component Testing -- Vue basic component mount tests', function() {\n  xit('run a single Vue component test with missing component', function() {\n    this.timeout(100000);\n\n    const testsPath = path.join(__dirname, '../samples/vue/tests/formTest--notFound.js');\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 100,\n      retryAssertionTimeout: 150,\n\n      reporter(results) {\n        assert.strictEqual(results.errors, 1);\n        assert.strictEqual(results.failed, 0);\n        assert.strictEqual(results.passed, 0);\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.lastError.name, 'NightwatchMountError');\n        assert.strictEqual(results.lastError.message, 'time out reached (200ms) while waiting for component to mount.');\n        assert.deepStrictEqual(results.lastError.help, [\n          'run nightwatch with --devtools and --debug flags (Chrome only)',\n          'investigate the error in the browser console'\n        ]);\n      }\n    };\n\n    return runTests({\n      source: testsPath,\n      headless: true,\n      devtools: false,\n      debug: false,\n      config: path.join(__dirname, '../samples/vue/nightwatch.conf.js')\n    }, {\n      globals,\n      output: false,\n      silent: true,\n      disable_colors: false,\n      '@nightwatch/vue': {\n        hooksRetryTimeout: 200,\n        hooksRetryInterval: 50\n      }\n    });\n  });\n\n  it('run a single vue component test', function() {\n    this.timeout(100000);\n\n    const testsPath = path.join(__dirname, '../samples/vue/tests/formTest.js');\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 100,\n      retryAssertionTimeout: 150,\n\n      reporter(results) {\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(results.failed, 0);\n        assert.strictEqual(results.passed, 1);\n      }\n    };\n\n    return runTests({\n      source: testsPath,\n      headless: true,\n      debug: false,\n      devtools: false,\n      config: path.join(__dirname, '../samples/vue/nightwatch.conf.js')\n    }, {\n      globals,\n      output: false,\n      silent: false,\n      disable_colors: false,\n      '@nightwatch/vue': {\n        hooksRetryTimeout: 1000,\n        hooksRetryInterval: 100\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/component-tests/src/testRunnJSXReact.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst {runTests} = common.require('index.js');\nconst isCI = require('is-ci');\n\ndescribe('Component Testing -- React JSX component tests', function() {\n  it('run a single component test without proper config', async function() {\n    const testsPath = path.join(__dirname, '../samples/react/tests/Form.spec--_with-$hooks.jsx');\n    const globals = {};\n\n    let error;\n    try {\n      await runTests({\n        source: testsPath,\n        headless: true,\n        config: path.join(__dirname, '../samples/nightwatch.conf-noplugins.js')\n      }, {\n        globals,\n        output: false,\n        silent: false,\n        disable_colors: false\n      });\n    } catch (err) {\n      error = err;\n    }\n\n    assert.ok(error instanceof SyntaxError);\n    assert.ok(error.message.includes('Cannot use import statement outside a module'));\n    assert.ok(error.detailedErr.includes('In order to be able to load JSX files, one of these plugins is needed:'));\n    assert.ok(error.detailedErr.includes('- @nightwatch/react'));\n    assert.ok(error.detailedErr.includes('- @nightwatch/storybook (only if using Storybook in your project)'));\n  });\n\n  it.skip('run a single JSX React component test', function() {\n    this.retries(2);\n    this.timeout(100000);\n\n    const testsPath = path.join(__dirname, '../samples/react/tests/Form.spec--_with-$hooks.jsx');\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 100,\n      retryAssertionTimeout: 150,\n\n      reporter(results) {\n        assert.strictEqual(results.passed, 7);\n        assert.strictEqual(results.failed, 0);\n        assert.strictEqual(results.errors, 0);\n      }\n    };\n\n    return runTests({\n      source: testsPath,\n      headless: true,\n      debug: false,\n      devtools: false,\n      config: path.join(__dirname, '../samples/react/nightwatch.conf.js')\n    }, {\n      globals,\n      output: false,\n      silent: false,\n      disable_colors: false,\n      '@nightwatch/react': {\n        hooksRetryTimeout: 200,\n        hooksRetryInterval: 50\n      }\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/chainingCommands/testCommands.js",
    "content": "const {Given, Then} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n\n  return browser.url('http://localhost');\n});\n\nThen('I check if badElement is present', function() {\n\n  return browser.waitForElementPresent('#badElement').click('#webdriver');\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/customCommands/testCucumberWithCustomWait.js",
    "content": "const {Given, Then} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n\n  return browser.url('http://localhost');\n});\n\nThen('I check if badElement is present', async function() {\n\n  await browser.customWaitForPresent('#badElement');\n  await browser.click('#webdriver');\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/integration/sample.feature",
    "content": "Feature: Sample Feature\n@pass\nScenario: Sample Scenario\n    Given I navigate to localhost\n    Then I check if webdriver is present\n\n@expect\nScenario: Sample Scenario with expect\n    Given I navigate to localhost\n    Then I check if webdriver is present and contains text\n\n@fail\nScenario: Sample test with failures\n    Given I navigate to localhost\n    Then I check if badElement is present"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js",
    "content": "const assert = require('assert');\nconst {Given, Then, After} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls++;\n\n  return browser.navigateTo('http://localhost');\n});\n\nThen('I check if webdriver is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#webdriver');\n});\n\nThen('I check if webdriver is present and contains text', async function() {\n  browser.globals.test_calls++;\n\n  await browser.expect.element('#webdriver').text.to.contain('xx')\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#badElement');\n});\n\nAfter(function() {\n  assert.strictEqual(browser.globals.test_calls, 2);\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/integration/testWithFailures.js",
    "content": "const {Given, Then} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls++;\n\n  return browser.url('http://localhost');\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#badElement');\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/parallel/sample.feature",
    "content": "Feature: Sample Feature\n@pass\nScenario: Sample Scenario\n    Given I navigate to localhost\n    Then I check if webdriver is present\n\n@expect\nScenario: Sample Scenario with expect\n    Given I navigate to localhost\n    Then I check if webdriver is present and contains text\n\n@fail\nScenario: Sample test with failures\n    Given I navigate to localhost\n    Then I check if badElement is present"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/parallel/testSample.js",
    "content": "const assert = require('assert');\nconst {Given, Then, After} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls++;\n\n  return browser.navigateTo('http://localhost');\n});\n\nThen('I check if webdriver is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#webdriver');\n});\n\nThen('I check if webdriver is present and contains text', async function() {\n  browser.globals.test_calls++;\n\n  await browser.expect.element('#webdriver').text.to.contain('xx')\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#badElement');\n});\n\nAfter(function() {\n  assert.strictEqual(browser.globals.test_calls, 2);\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/parallel/testWithFailures.js",
    "content": "const {Given, Then} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls++;\n  return browser.url('http://localhost');\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n  return browser.assert.elementPresent('#badElement');\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/parallel-formatters/sample.feature",
    "content": "Feature: Sample Feature\n@pass\nScenario: Sample Scenario\n    Given I navigate to localhost\n    Then I check if webdriver is present\n\n@expect\nScenario: Sample Scenario with expect\n    Given I navigate to localhost\n    Then I check if webdriver is present and contains text\n\n@fail\nScenario: Sample test with failures\n    Given I navigate to localhost\n    Then I check if badElement is present"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/parallel-formatters/testSample.js",
    "content": "const assert = require('assert');\nconst {Given, Then, After} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls++;\n\n  return browser.navigateTo('http://localhost');\n});\n\nThen('I check if webdriver is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#webdriver');\n});\n\nThen('I check if webdriver is present and contains text', async function() {\n  browser.globals.test_calls++;\n\n  await browser.expect.element('#webdriver').text.to.contain('xx')\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#badElement');\n});\n\nAfter(function() {\n  assert.strictEqual(browser.globals.test_calls, 2);\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/parallel-formatters/testWithFailures.js",
    "content": "const {Given, Then} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls++;\n  return browser.url('http://localhost');\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n  return browser.assert.elementPresent('#badElement');\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/parallelWithMultipleDefinition/testExpect.js",
    "content": "const {Then} = require('@cucumber/cucumber');\n\n\nThen('I check if webdriver is present and contains text', async function() {\n  browser.globals.test_calls++;\n\n  await browser.expect.element('#webdriver').text.to.contain('xx');\n});\n"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/parallelWithMultipleDefinition/testSample.js",
    "content": "const {Given, Then} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n\n  return browser.navigateTo('http://localhost');\n});\n\nThen('I check if webdriver is present', function() {\n\n  return browser.assert.elementPresent('#webdriver');\n});\n\n"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/with-extra-setup/_extra_setup.js",
    "content": "const {Before, After} = require('@cucumber/cucumber');\n\nBefore(async function(testCase) {\n  if (!this.client) {\n    console.error('Nightwatch client was not created.');\n\n    return;\n  }\n\n  this.client.updateCapabilities({\n    testCap: 'testing'\n  });\n\n  this.browser = await this.client.launchBrowser();\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/with-extra-setup/sample.feature",
    "content": "Feature: Sample Feature\n@pass\nScenario: Sample Scenario\n    Given I navigate to localhost\n    Then I check if webdriver is present\n\n@expect\nScenario: Sample Scenario with expect\n    Given I navigate to localhost\n    Then I check if webdriver is present and contains text\n\n@fail\nScenario: Sample test with failures\n    Given I navigate to localhost\n    Then I check if badElement is present"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/with-extra-setup/testSample.js",
    "content": "const assert = require('assert');\nconst {Given, Then, After} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls = 0;\n  browser.globals.test_calls++;\n\n  return browser.navigateTo('http://localhost');\n});\n\nThen('I check if webdriver is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#webdriver');\n});\n\nThen('I check if webdriver is present and contains text', async function() {\n  browser.globals.test_calls++;\n\n  await browser.expect.element('#webdriver').text.to.contain('xx')\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#badElement');\n});\n\nAfter(function() {\n  assert.strictEqual(browser.globals.test_calls, 2);\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/with-extra-setup/testWithFailures.js",
    "content": "const {Given, Then} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls++;\n  return browser.url('http://localhost');\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n  return browser.assert.elementPresent('#badElement');\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/with-modified-settings/plugin/index.js",
    "content": ""
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/with-modified-settings/plugin/nightwatch/globals.js",
    "content": "module.exports = {\n  before(settings) {\n    settings.desiredCapabilities.browserName = 'chrome';\n  }\n};"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/with-modified-settings/testSample.js",
    "content": "const assert = require('assert');\nconst {Given, Then, After} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls = 0;\n  browser.globals.test_calls++;\n\n  return browser.navigateTo('http://localhost');\n});\n\nThen('I check if webdriver is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#webdriver');\n});\n\nThen('I check if webdriver is present and contains text', async function() {\n  browser.globals.test_calls++;\n\n  await browser.expect.element('#webdriver').text.to.contain('xx')\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#badElement');\n});\n\nAfter(function() {\n  assert.strictEqual(browser.globals.test_calls, 2);\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/withexpect/sample.feature",
    "content": "Feature: Sample Feature\n@pass\nScenario: Sample Scenario\n    Given I navigate to localhost\n    Then I check if webdriver is present\n\n@expect\nScenario: Sample Scenario with expect\n    Given I navigate to localhost\n    Then I check if webdriver is present and contains text\n\n@fail\nScenario: Sample test with failures\n    Given I navigate to localhost\n    Then I check if badElement is present"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/withexpect/testSample.js",
    "content": "const assert = require('assert');\nconst {Given, Then, After} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls++;\n\n  return browser.navigateTo('http://localhost');\n});\n\nThen('I check if webdriver is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#webdriver');\n});\n\nThen('I check if webdriver is present and contains text', async function() {\n  browser.globals.test_calls++;\n\n  await browser.expect.element('#webdriver').text.to.contain('xx')\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n\n  return browser.assert.elementPresent('#badElement');\n});\n\nAfter(function() {\n  assert.strictEqual(browser.globals.test_calls, 2);\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/withexpect/testWithFailures.js",
    "content": "const {Given, Then} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls++;\n  return browser.url('http://localhost');\n});\n\nThen('I check if badElement is present', function() {\n  browser.globals.test_calls++;\n  return browser.assert.elementPresent('#badElement');\n});"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/withwaitFor/sample.feature",
    "content": "Feature: Sample Feature\n\n@fail\nScenario: Sample test with failures\n    Given I navigate to localhost\n    Then I wait for badElement to be present"
  },
  {
    "path": "test/cucumber-integration-tests/sample_cucumber_tests/withwaitFor/testWithFailures.js",
    "content": "const {Given, Then} = require('@cucumber/cucumber');\n\nGiven('I navigate to localhost', function() {\n  browser.globals.test_calls++;\n\n  return browser.url('http://localhost');\n});\n\nThen('I wait for badElement to be present', function() {\n  browser.globals.test_calls++;\n\n  return browser.waitForElementPresent('#badElement');\n});"
  },
  {
    "path": "test/cucumber-integration-tests/testCucumberTestsInParallel.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst Globals = require('../lib/globals/commands.js');\nconst commandMocks = require('../lib/command-mocks.js');\nconst common = require('../common.js');\nconst MockServer = require('../lib/mockserver.js');\n\ndescribe('Cucumber integration - parallel running single formatter', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init(null, {port: 10190});\n    this.server.on('listening', () => done());\n  });\n\n  afterEach(function (done) {\n    Globals.afterEach.call(this, done);\n  });\n\n  it('testCucumberSampleTests in parallel with single formatter', function () {\n    const source = [\n      path.join(__dirname, './sample_cucumber_tests/parallel/testSample.js')\n    ];\n\n    const {runTests} = common.require('index.js');\n\n    return runTests({\n      source,\n      parallel: true,\n      verbose: false,\n      timeout: 10,\n      format: 'progress',\n      config: path.join(__dirname, '../extra/cucumber-config-parallel.js'),\n      'format-options': '',\n      ['retry-interval']: 5,\n      ['persist-globals']: true,\n      ['webdriver-host']: 'localhost',\n      ['start-process']: false,\n      ['webdriver-port']: 10190\n    }, {})\n      .then(errorOrFailed => {\n        assert.strictEqual(errorOrFailed, true);\n      });\n  });\n\n  it('testCucumberSampleTests in parallel with multiple step definition files', function () {\n\n    commandMocks.elementText('5cc459b8-36a8-3042-8b4a-258883ea642b', 'xx');\n\n    const source = [\n      path.join(__dirname, './sample_cucumber_tests/parallelWithMultipleDefinition')\n    ];\n\n    const {runTests} = common.require('index.js');\n\n    return runTests({\n      source,\n      parallel: true,\n      verbose: true,\n      timeout: 10,\n      env: 'chrome',\n      silent: false,\n      tags: ['not @fail'],\n      format: 'progress',\n      config: path.join(__dirname, '../extra/cucumber-config-parallel.js'),\n      'format-options': '',\n      ['retry-interval']: 5,\n      ['persist-globals']: true,\n      ['webdriver-host']: 'localhost',\n      ['start-process']: false,\n      ['webdriver-port']: 10190\n    }, {})\n      .then(errorOrFailed => {\n        assert.strictEqual(errorOrFailed, false);\n      });\n  });\n\n  it('testCucumberSampleTests in parallel environments with multiple step definition files', function () {\n\n    commandMocks.elementText('5cc459b8-36a8-3042-8b4a-258883ea642b', 'xx');\n\n    const source = [\n      path.join(__dirname, './sample_cucumber_tests/parallelWithMultipleDefinition')\n    ];\n\n    const {runTests} = common.require('index.js');\n\n    return runTests({\n      source,\n      parallel: true,\n      verbose: true,\n      timeout: 10,\n      env: 'chrome,firefox',\n      silent: false,\n      tags: ['not @fail'],\n      format: 'progress',\n      config: path.join(__dirname, '../extra/cucumber-config-parallel.js'),\n      'format-options': '',\n      ['retry-interval']: 5,\n      ['persist-globals']: true,\n      ['webdriver-host']: 'localhost',\n      ['start-process']: false,\n      ['webdriver-port']: 10190\n    }, {})\n      .then(errorOrFailed => {\n        assert.strictEqual(errorOrFailed, false);\n      });\n  });\n});\n"
  },
  {
    "path": "test/cucumber-integration-tests/testCucumberTestsParallelFormatters.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst Globals = require('../lib/globals/commands.js');\nconst common = require('../common.js');\nconst MockServer = require('../lib/mockserver.js');\nconst {runTests} = common.require('index.js');\n\ndescribe('Cucumber integration - parallel running multiple formatters', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init(null, {port: 10191});\n    this.server.on('listening', () => done());\n  });\n\n  afterEach(function(done) {\n    Globals.afterEach.call(this, done);\n  });\n\n  it('testCucumberSampleTests in parallel with multiple formatters', function() {\n    const source = [\n      path.join(__dirname, './sample_cucumber_tests/parallel-formatters/testSample.js')\n    ];\n\n    return runTests({\n      source,\n      parallel: true,\n      verbose: false,\n      timeout: 10,\n      format: ['progress', 'usage'],\n      config: path.join(__dirname, '../extra/cucumber-config-parallel-formatters.js'),\n      'format-options': '',\n      ['retry-interval']: 5,\n      ['persist-globals']: true,\n      ['webdriver-host']: 'localhost',\n      ['start-process']: false,\n      ['webdriver-port']: 10191\n    }, {})\n      .then(errorOrFailed => {\n        assert.strictEqual(errorOrFailed, true);\n      });\n  });\n});"
  },
  {
    "path": "test/cucumber-integration-tests/testCucumberTestsWithExpect.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst Globals = require('../lib/globals/commands.js');\nconst common = require('../common.js');\nconst MockServer = require('../lib/mockserver.js');\nconst {runTests} = common.require('index.js');\nconst {settings} = common;\n\ndescribe('Cucumber integration with .expect APIs', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init(null, {port: 10192});\n    this.server.on('listening', () => done());\n  });\n\n  afterEach(function(done) {\n    Globals.afterEach.call(this, done);\n  });\n\n  it('testCucumberSampleTests -- with expect async', function() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/text',\n      statusCode: 200,\n      method: 'GET',\n      response: {\n        value: 'jean sibelius'\n      },\n      times: 3\n    });\n\n    const source = [path.join(__dirname, './sample_cucumber_tests/withexpect/testSample.js')];\n\n    return runTests({\n      source,\n      tags: ['@expect'],\n      verbose: false,\n      config: path.join(__dirname, '../extra/cucumber-config-expect.js')\n    }, settings({\n      silent: false,\n      output: false,\n      globals: {\n        waitForConditionTimeout: 10,\n        waitForConditionPollInterval: 50\n      }\n    })).then(failures => {\n      assert.strictEqual(failures, true, 'Cucumber should have test failures');\n    });\n  });\n\n  it('testCucumberSampleTests -- nightwatch formatter live events', function() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/text',\n      statusCode: 200,\n      method: 'GET',\n      response: {\n        value: 'jean sibelius'\n      },\n      times: 3\n    });\n\n    const source = [path.join(__dirname, './sample_cucumber_tests/withexpect/testSample.js')];\n\n    return runTests({\n      source,\n      verbose: false,\n      config: path.join(__dirname, '../extra/cucumber-config-events.js')\n    }, settings({\n      silent: false,\n      output: false,\n      globals: {\n        waitForConditionTimeout: 10,\n        waitForConditionPollInterval: 50\n      }\n    })).then(failures => {\n      assert.strictEqual(failures, true, 'Cucumber should have test failures');\n    });\n  });\n});\n"
  },
  {
    "path": "test/cucumber-integration-tests/testCucumberTestsWithExtras.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst Globals = require('../lib/globals/commands.js');\nconst common = require('../common.js');\nconst MockServer = require('../lib/mockserver.js');\nconst {runTests} = common.require('index.js');\n\ndescribe('Cucumber integration - with extras', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init(null, {port: 10193});\n    this.server.on('listening', () => done());\n  });\n\n  afterEach(function(done) {\n    Globals.afterEach.call(this, done);\n  });\n\n  it('testCucumberSampleTests with disable_session_autocreate=true', function() {\n    const source = [path.join(__dirname, './sample_cucumber_tests/with-extra-setup/testSample.js')];\n\n    MockServer.addMock({\n      url: '/wd/hub/session',\n      method: 'POST',\n      statusCode: 201,\n      postdata: {\n        desiredCapabilities: {\n          browserName: 'firefox',\n          name: 'Sample Scenario',\n          testCap: 'testing'\n        },\n        capabilities: {alwaysMatch: {browserName: 'firefox'}}\n      },\n      response: {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {browserName: 'firefox', browserVersion: 'TEST_firefox'},\n        state: null\n      }\n    }, true);\n\n    return runTests({\n      source,\n      tags: ['@pass'],\n      verbose: false,\n      config: path.join(__dirname, '../extra/cucumber-config-noautostart.js'),\n      require: path.join(__dirname, './sample_cucumber_tests/with-extra-setup/_extra_setup.js')\n    }, {})\n      .then(failures => {\n        assert.strictEqual(failures, false);\n      });\n  });\n\n});"
  },
  {
    "path": "test/cucumber-integration-tests/testCucumberTestsWithModifiedSettings.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst Globals = require('../lib/globals/commands.js');\nconst common = require('../common.js');\nconst MockServer = require('../lib/mockserver.js');\nconst {runTests} = common.require('index.js');\n\ndescribe('Cucumber integration - with modified settings in plugin', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init(null, {port: 10195});\n    this.server.on('listening', () => done());\n  });\n\n  afterEach(function(done) {\n    Globals.afterEach.call(this, done);\n  });\n\n  it('testCucumberSampleTests with browsername modified (chrome) in plugin global hook', function() {\n    const source = [path.join(__dirname, './sample_cucumber_tests/with-modified-settings/testSample.js')];\n\n\n    const pluginPath = [path.join(__dirname, './sample_cucumber_tests/with-modified-settings/plugin')];\n\n    MockServer.addMock({\n      url: '/wd/hub/session',\n      method: 'POST',\n      statusCode: 201,\n      postdata: {\n        capabilities: {\n          firstMatch: [{}],\n          alwaysMatch: {browserName: 'chrome', 'goog:chromeOptions': {}}\n        }\n      },\n      response: {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {browserName: 'chrome', browserVersion: 'TEST_chrome'},\n        state: null\n      }\n    }, true);\n\n\n    // modify browserName to chrome in plugin global hook\n    return runTests({\n      source,\n      tags: ['@pass'],\n      verbose: false, \n      config: path.join(__dirname, '../extra/cucumber-config.js')\n    }, {\n      plugins: pluginPath\n    })\n      .then(failures => {\n        assert.strictEqual(failures, false);\n      });\n  });\n\n});"
  },
  {
    "path": "test/cucumber-integration-tests/testCucumberTestsWithWaitFor.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst Globals = require('../lib/globals/commands.js');\nconst common = require('../common.js');\nconst MockServer = require('../lib/mockserver.js');\nconst {runTests} = common.require('index.js');\nconst {settings} = common;\n\ndescribe('Cucumber integration with .expect APIs', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init(null, {port: 10192});\n    this.server.on('listening', () => done());\n  });\n\n  afterEach(function(done) {\n    Globals.afterEach.call(this, done);\n  });\n\n  it('testCucumberSampleTests -- with waitFor failure', function() {\n    const source = [path.join(__dirname, './sample_cucumber_tests/withWaitFor/testWithFailures.js')];\n\n    return runTests({\n      source,\n      tags: ['@fail'],\n      verbose: false,\n      config: path.join(__dirname, '../extra/cucumber-config-waitFor.js')\n    }, settings({\n      silent: false,\n      output: false,\n      globals: {\n        waitForConditionTimeout: 10,\n        waitForConditionPollInterval: 50\n      }\n    })).then(failures => {\n      assert.strictEqual(failures, true, 'Cucumber should have test failures');\n    });\n  });\n\n});"
  },
  {
    "path": "test/extra/assertions/.dotrc",
    "content": ""
  },
  {
    "path": "test/extra/assertions/customAssertion.js",
    "content": "var assert = require('assert');\nexports.assertion = function(testVal, done) {\n  this.expected = true;\n  this.message = '';\n\n  this.pass = function(value) {\n    assert.strictEqual(testVal, value, 'Value passed to the `pass` method is incorrect.');\n\n    return value === this.expected;\n  };\n\n  this.value = function(result) {\n    assert.deepStrictEqual(result, {\n      value: testVal\n    }, 'Value passed to the `value` method is incorrect.');\n\n    return result.value;\n  };\n\n  this.command = function(callback) {\n    assert.strictEqual(callback.length, 1, 'Callback expects 1 single argument.');\n    assert.ok(callback.name.indexOf('commandCallback') > -1);\n    assert.ok(typeof this.api !== 'undefined');\n\n    callback({\n      value: testVal\n    });\n\n    done();\n\n    return this;\n  };\n\n};"
  },
  {
    "path": "test/extra/assertions/customAssertionWithSelector.js",
    "content": "/**\n * @param {object} element\n * @param variable\n * @params {function} [done]\n */\nexports.assertion = function(element, variable, done) {\n  this.expected = true;\n  this.selector = element.selector;\n  this.element = element;\n  this.variable = variable;\n  this.message = '';\n  this.rescheduleInterval = 50;\n  this.retryAssertionTimeout = 100;\n\n  this.pass = function(value) {\n    return value === this.variable;\n  };\n\n  this.value = function(result) {\n    return result.value;\n  };\n\n  this.command = function(callback) {\n    callback({\n      value: 0\n    });\n  };\n\n};\n"
  },
  {
    "path": "test/extra/commands/_otherPerform.js",
    "content": "var util = require('util');\nvar events = require('events');\n\nfunction Command() {\n  events.EventEmitter.call(this);\n}\nutil.inherits(Command, events.EventEmitter);\n\nCommand.prototype.command = function(callback) {\n  var self = this;\n  this.api.perform(function() {\n    setTimeout(function() {\n      if (callback) {\n        callback();\n      }\n      self.emit('complete');\n    }, 10);\n  });\n\n  return this;\n};\n\nmodule.exports = Command;\n"
  },
  {
    "path": "test/extra/commands/autoInvoke/customCommandInvoke.js",
    "content": "module.exports = class CustomCommandInvoke {\n  command() {\n    return this.api.perform(function() {\n      this.globals.count++;\n    });\n  }\n};\n\nmodule.exports.autoInvoke = true;"
  },
  {
    "path": "test/extra/commands/customClearValue.js",
    "content": "exports.command = function(selector, cb) {\n\n  this.clearValue(selector, function(result) {\n    cb(selector, result);\n  });\n\n};\n"
  },
  {
    "path": "test/extra/commands/customCommand.js",
    "content": "module.exports = {\n  command: function(cb) {\n    return this.perform(cb);\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/customCommandAppendResults.js",
    "content": "module.exports = class AppendResult {\n  command() {\n    const {name} = this.client.reporter.currentTest;\n    const {testResults} = this.client.reporter;\n    testResults.appendTestResult({\n      [name]: {\n        customReport: {\n          success: true\n        }\n      }\n    });\n\n  }\n};"
  },
  {
    "path": "test/extra/commands/customCommandConstructor.js",
    "content": "function Command() {}\nCommand.prototype.command = function() {\n  return this;\n};\n\nmodule.exports = Command;\n"
  },
  {
    "path": "test/extra/commands/customCommandWithFailure.js",
    "content": "module.exports = {\n  command: function(cb) {\n    this.waitForElementPresent('#badElement', 100);\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/customCommandWithFailureClass.js",
    "content": "module.exports = class CustomCommandWithFailureClass{\n  async command() {\n    await this.api.waitForElementPresent('#badElement', 100);\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/customCommandWithSelector.js",
    "content": "exports.command = function(selector, cb) {\n\n  this.perform(function() {\n    cb(selector);\n  });\n\n  return this;\n};\n"
  },
  {
    "path": "test/extra/commands/customElementPresent.js",
    "content": "const assert = require('assert');\nconst common = require('../../common.js');\nconst waitForElementPresent = common.require('api/element-commands/waitForElementPresent.js');\n\nmodule.exports = class CustomElement extends waitForElementPresent {\n  constructor() {\n    super();\n\n    this.expectedValue = 'custom';\n  }\n\n  async command() {\n    await super.command();\n\n    // check that this.transportActions are available\n    assert.strictEqual(typeof this.transportActions, 'object');\n\n    const getUrl = await this.transportActions.getCurrentUrl();\n    assert.deepStrictEqual(getUrl, {\n      status: 0,\n      value: 'http://localhost'\n    });\n\n    assert.strictEqual(typeof this.transportActions.getStatus, 'function');\n    assert.strictEqual(typeof this.transportActions.setTimeoutType, 'function');\n\n    const response = await this.httpRequest({\n      path: '/session/:sessionId/url',\n      sessionId: '1352110219202',\n      host: '',\n      port: '',\n      data: {\n        url: 'http://localhost/test_url'\n      },\n      method: 'POST'\n    });\n\n    assert.deepStrictEqual(response, {status: 0});\n\n    this.emit('complete');\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/customExecute.js",
    "content": "module.exports = {\n  namespacedAliases: ['document.customExecute'],\n\n  command: function(data, callback = function() {}) {\n    this.execute(function(data) {return data}, [data], callback);\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/customPauseWithNamespacedAlias.js",
    "content": "module.exports = class CustomPause {\n  static get namespacedAliases() {\n    return ['newPause', 'sampleNamespace.amazingPause', 'fantasticNamespace.subNamespace.fantasticPause'];\n  }\n\n  command(timeout) {\n    if (typeof timeout !== 'number') {\n      throw new Error('First argument should be a number.');\n    }\n\n    this.pause(200);\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/customPerform.js",
    "content": "var util = require('util');\nvar events = require('events');\n\nfunction Command() {\n  events.EventEmitter.call(this);\n}\nutil.inherits(Command, events.EventEmitter);\n\nCommand.prototype.command = function(callback) {\n  var self = this;\n  this.api.perform(function() {\n    setImmediate(function() {\n      if (callback) {\n        callback();\n      }\n      self.emit('complete');\n    });\n  });\n\n  return this;\n};\n\nmodule.exports = Command;\n"
  },
  {
    "path": "test/extra/commands/customQuit.js",
    "content": "const {quit: Quit} = require('../../../api');\n\nmodule.exports = class CustomQuit extends Quit {\n  async command(callback, quitCallback) {\n    let result;\n    this.transport.once('session:finished', (reason) => {\n      callback({\n        client: this.client,\n        reason,\n        result\n      });\n    });\n\n    result = await super.command(function(result) {\n      return quitCallback(result);\n    });\n  }\n};"
  },
  {
    "path": "test/extra/commands/customWaitForPresent.js",
    "content": "module.exports = class CustomWaitForPresent {\n  async command(selector) {\n    await this.api.waitForElementPresent(selector);\n  }\n};"
  },
  {
    "path": "test/extra/commands/es6async/basicPerform.js",
    "content": "module.exports = {\n  command(cb) {\n    this.pause(10).perform(cb);\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/es6async/basicPerformWithFluentApi.js",
    "content": "module.exports = {\n  async command(cb) {\n    this.pause(10).perform(cb);\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/es6async/customExecuteAsync.js",
    "content": "exports.command = async function(data, callback) {\n  const startTime = new Date();\n\n  await this.execute(function(data) {return data}, [data], async function(result) {\n    const res = await this.pause(100);\n\n    const endTime = await this.perform(function() {\n      return new Date() - startTime;\n    });\n\n    callback(endTime);\n  });\n};"
  },
  {
    "path": "test/extra/commands/es6async/customFindElements.js",
    "content": "module.exports.command = function(selector, callback = function() {}) {\n  this.findElements({\n    selector,\n    suppressNotFoundErrors: true\n  }, function(result) {\n    callback(result.value);\n  });\n};"
  },
  {
    "path": "test/extra/commands/es6async/customFindElementsES6.js",
    "content": "module.exports.command = async function(selector, callback = function() {}) {\n  await this.url();\n\n  const elements = await this.findElements({\n    selector,\n    suppressNotFoundErrors: true\n  });\n\n  callback.call(this, elements);\n\n  return elements;\n};"
  },
  {
    "path": "test/extra/commands/es6async/customPerform.js",
    "content": "module.exports = {\n  async command(cb) {\n    this.pause(10);\n\n    await this.perform(cb);\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/es6async/customPerformClass.js",
    "content": "module.exports = class {\n  async command(cb) {\n    this.api.pause(10);\n    this.api.globals.logResult = await this.api.getLog('browser');\n\n    await this.api.perform(cb);\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/es6async/customVisible.js",
    "content": "module.exports = class customVisible {\n  async command(selector) {\n    await this.api.assert.visible(selector);\n  }\n};"
  },
  {
    "path": "test/extra/commands/es6async/getEmail.js",
    "content": "module.exports = class GetEmailBody {\n  async command(type) {\n    let returnValue;\n\n    switch(type){\n      case 1:\n        try {\n          returnValue = await getEmail();\n        } catch (err) {\n          returnValue = {\n            status: -1,\n            error: err.message\n          }\n        }\n    \n        return returnValue;\n\n      case 2:\n        try {\n          returnValue = await getEmail();\n        } catch (err) {\n          returnValue = {\n            status: -1,\n            error: err\n          }\n        }\n    \n        return returnValue;\n\n      case 3:\n        return await getEmail();\n    }\n  }\n}\n\nconst getEmail = () => new Promise((resolve, reject) => {\n  reject(new Error('Email not found'));\n});"
  },
  {
    "path": "test/extra/commands/other/otherCommand.js",
    "content": "module.exports = class OtherCommand {\n  command() {\n    return this.api.pause(10);\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/returnFn/customCommandReturnFn.js",
    "content": "module.exports = class CustomCommandReturnFn {\n  static get returnFn() {\n    return function(node, api) {\n      api.globals.count++;\n\n      return {\n        status: 0\n      };\n    };\n  }\n\n  command() {\n    this.api.perform(function() {\n      this.globals.count++;\n    });\n  }\n};\n"
  },
  {
    "path": "test/extra/commands/typescript/tsWait.js",
    "content": "// NOTE: this file represents a compiled version of `tsWait.ts` generated by `tsc`.\n\nmodule.exports.command = function(timeout = 0) {\n  return this\n    .perform(() => console.log(`Waiting ${timeout}ms`))\n    .pause(timeout);\n};\n"
  },
  {
    "path": "test/extra/commands/typescript/tsWait.ts",
    "content": "// NOTE: by default nightwatch does not know how to execute .ts files hence\n// additional steps are required. For example compiling them to .js before\n// running nightwatch using `tsc`. This will create a second file, wait.js\n// in this case, that is executable by nightwatch (NodeJS).\n\nexport function command(timeout = 0) {\n  return this\n    .perform(() => console.log(`Waiting ${timeout}ms`))\n    .pause(timeout);\n}\n"
  },
  {
    "path": "test/extra/cucumber-config-events.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = {\n  selenium: {\n    port: 10192,\n    host: 'localhost'\n  },\n\n  persist_globals: true,\n  output_folder: false,\n\n  webdriver: {\n    start_process: false\n  },\n\n  globals: {\n    test_calls: 0,\n    waitForConditionTimeout: 20,\n    retryAssertionTimeout: 20,\n    waitForConditionPollInterval: 10,\n    registerEventHandlers: function(eventBroadcaster) {\n      eventBroadcaster.on('TestCaseStarted', (args) => {\n        assert.deepStrictEqual(Object.keys(args), ['envelope', 'report']);\n      });\n\n      eventBroadcaster.on('TestCaseFinished', (args) => {\n        assert.deepStrictEqual(Object.keys(args), ['envelope', 'report']);\n      });\n\n      eventBroadcaster.on('TestStepStarted', (args) => {\n        assert.deepStrictEqual(Object.keys(args), ['envelope', 'report']);\n      });\n\n      eventBroadcaster.on('TestStepFinished', (args) => {\n        assert.deepStrictEqual(Object.keys(args), ['envelope', 'report']);\n      });\n\n      eventBroadcaster.on('TestStarted', (args) => {\n        assert.deepStrictEqual(Object.keys(args), ['envelope', 'report']);\n      });\n\n      eventBroadcaster.on('TestFinished', (args) => {\n        assert.deepStrictEqual(Object.keys(args), ['envelope', 'report']);\n      });\n    }\n  },\n\n  test_runner: {\n    type: 'cucumber',\n    options: {\n      feature_path: path.join(__dirname, '../cucumber-integration-tests/sample_cucumber_tests/withexpect/sample.feature')\n    }\n  },\n  output: false,\n  silent: false\n};\n"
  },
  {
    "path": "test/extra/cucumber-config-expect.js",
    "content": "const path = require('path');\n\nmodule.exports = {\n  selenium: {\n    port: 10192,\n    host: 'localhost'\n  },\n\n  persist_globals: true,\n  output_folder: false,\n\n  webdriver: {\n    start_process: false\n  },\n\n  globals: {\n    test_calls: 0,\n    waitForConditionTimeout: 20,\n    retryAssertionTimeout: 20,\n    waitForConditionPollInterval: 10\n  },\n\n  test_runner: {\n    type: 'cucumber',\n    options: {\n      feature_path: path.join(__dirname, '../cucumber-integration-tests/sample_cucumber_tests/withexpect/sample.feature')\n    }\n  },\n  output: false,\n  silent: false\n}"
  },
  {
    "path": "test/extra/cucumber-config-noautostart.js",
    "content": "const path = require('path');\nconst lodashMerge = require('lodash/merge');\nconst lodashClone = require('lodash/clone');\n\nconst config = require('./cucumber-config.js');\nconst configCopy = lodashClone(config);\nconst settings = lodashMerge(configCopy, {\n  selenium: {\n    port: 10193\n  },\n  test_runner: {\n    options: {\n      auto_start_session: false,\n      feature_path: path.join(__dirname, '../cucumber-integration-tests/sample_cucumber_tests/with-extra-setup/sample.feature')\n    }\n  }\n});\n\nmodule.exports = settings;"
  },
  {
    "path": "test/extra/cucumber-config-parallel-formatters.js",
    "content": "const path = require('path');\n\nmodule.exports = {\n  selenium: {\n    port: 10191,\n    host: 'localhost'\n  },\n\n  persist_globals: true,\n  output_folder: false,\n\n  webdriver: {\n    start_process: false\n  },\n\n  globals: {\n    test_calls: 0,\n    waitForConditionTimeout: 20,\n    retryAssertionTimeout: 20,\n    waitForConditionPollInterval: 10\n  },\n\n  test_runner: {\n    type: 'cucumber',\n    options: {\n      feature_path: path.join(__dirname, '../cucumber-integration-tests/sample_cucumber_tests/parallel-formatters/sample.feature')\n    }\n  },\n  output: false,\n  silent: false\n}"
  },
  {
    "path": "test/extra/cucumber-config-parallel.js",
    "content": "const path = require('path');\n\nmodule.exports = {\n  selenium: {\n    port: 10190,\n    host: 'localhost'\n  },\n\n  persist_globals: true,\n  output_folder: false,\n\n  webdriver: {\n    start_process: false\n  },\n\n  globals: {\n    test_calls: 0,\n    waitForConditionTimeout: 20,\n    retryAssertionTimeout: 20,\n    waitForConditionPollInterval: 10\n  },\n\n  test_runner: {\n    type: 'cucumber',\n    options: {\n      feature_path: path.join(__dirname, '../cucumber-integration-tests/sample_cucumber_tests/parallel/sample.feature')\n    }\n  },\n\n  test_settings: {\n    chrome: {\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    },\n    firefox: {\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    }\n  },\n  output: false,\n  silent: false\n};"
  },
  {
    "path": "test/extra/cucumber-config-waitFor.js",
    "content": "const path = require('path');\n\nmodule.exports = {\n  selenium: {\n    port: 10192,\n    host: 'localhost'\n  },\n\n  persist_globals: true,\n  output_folder: false,\n\n  webdriver: {\n    start_process: false\n  },\n\n  globals: {\n    test_calls: 0,\n    waitForConditionTimeout: 20,\n    retryAssertionTimeout: 20,\n    waitForConditionPollInterval: 10\n  },\n\n  test_runner: {\n    type: 'cucumber',\n    options: {\n      feature_path: path.join(__dirname, '../cucumber-integration-tests/sample_cucumber_tests/withwaitFor/sample.feature')\n    }\n  },\n  output: false,\n  silent: false\n};"
  },
  {
    "path": "test/extra/cucumber-config.js",
    "content": "const path = require('path');\n\nmodule.exports = {\n  selenium: {\n    port: 10195,\n    host: 'localhost'\n  },\n\n  persist_globals: true,\n  output_folder: false,\n\n  webdriver: {\n    start_process: false\n  }, \n\n  custom_commands_path: [path.join(__dirname, './commands')],\n  \n  globals: {\n    test_calls: 0,\n    waitForConditionTimeout: 20,\n    retryAssertionTimeout: 20,\n    waitForConditionPollInterval: 10\n  },\n\n  test_runner: {\n    type: 'cucumber',\n    options: {\n      feature_path: path.join(__dirname, '../cucumber-integration-tests/sample_cucumber_tests/integration/sample.feature')\n    }\n  },\n  test_settings: {\n    browserstack: {\n      selenium: {\n        host: 'hub-cloud.browserstack.com',\n        port: 443\n      },\n      desiredCapabilities: {\n        'browserstack.user': 'test-access-user',\n        'browserstack.key': 'test-access-key',\n        browserName: 'chrome'\n      }\n    }\n  }\n};"
  },
  {
    "path": "test/extra/existing-custom-commands/click.js",
    "content": "module.exports.command = function() {\n\n}"
  },
  {
    "path": "test/extra/external-globals-async.js",
    "content": "const assert = require('assert');\n\nmodule.exports = {\n  'default': {},\n\n  async before() {\n    this.isFungus = true;\n  },\n\n  async beforeEach(client) {\n    expect(this.isFungus).to.be.true;\n\n    return new Promise(resolve => {\n      setTimeout(resolve, 500);\n    });\n  },\n\n  async afterEach(client) {\n    assert.strictEqual(client.globals.isFungus, true);\n  },\n\n  async reporter(results) {\n    assert.ok('modules' in results);\n\n    if (results.lastError instanceof Error) {\n      throw results.lastError;\n    }\n\n    assert.strictEqual(this.reporterCount, 0);\n    assert.strictEqual(this.isFungus, true);\n\n    this.reporterCount++;\n  }\n};\n"
  },
  {
    "path": "test/extra/external-globals.js",
    "content": "const assert = require('assert');\n\nmodule.exports = {\n  'default': {},\n\n  async before() {\n    this.isFungus = true;\n  },\n\n  beforeEach(client, done) {\n    done()\n  },\n\n  afterEach(client, done) {\n    assert.strictEqual(client.globals.isFungus, true);\n\n    done();\n  },\n\n  reporter(results) {\n    assert.ok('modules' in results);\n    if (results.lastError instanceof Error) {\n      throw results.lastError;\n    }\n\n    assert.strictEqual(this.reporterCount, 0);\n    assert.strictEqual(this.isFungus, true);\n\n    this.reporterCount++;\n  }\n};\n"
  },
  {
    "path": "test/extra/globals-err.js",
    "content": "// eslint-disable-next-line no-undef\n__unresolved__.exports = {\n  test: 1\n};"
  },
  {
    "path": "test/extra/globals.js",
    "content": "module.exports = {\n\n  before: function() {\n\n  },\n\n  after: function() {\n\n  }\n};"
  },
  {
    "path": "test/extra/minimalJsonReporter.json",
    "content": "{\n    \"modules\": {\n        \"demoTagTest\": {\n            \"modulePath\": \"./test/sampletests/tags/sample.js\",\n            \"status\": \"pass\"\n        },\n        \"demoTest\": {\n            \"modulePath\": \"./test/sampletests/simple/test/sample.js\",\n            \"status\": \"fail\"\n        }\n    }\n}\n"
  },
  {
    "path": "test/extra/mock-errors/sample-error.js",
    "content": "throw new Error('Error thrown in a user file');\n"
  },
  {
    "path": "test/extra/nightwatch.json",
    "content": "{\n  \"src_folders\" : [\"../sampletests\"],\n  \"output_folder\" : \"./output\",\n  \"custom_commands_path\" : \"\",\n  \"custom_assertions_path\" : \"\",\n  \"globals_path\" : \"./globals.js\",\n  \"test_workers\" : {\n    \"enabled\" : false\n  },\n  \"output\" : false,\n  \"selenium\" : {\n    \"start_process\" : false,\n    \"server_path\" : \"./bin/selenium-server.jar\"\n  },\n\n  \"test_settings\": {\n    \"default\" : {\n      \"silent\" : true,\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      },\n      \"filter\" : [\"async/**\"]\n    },\n\n    \"mixed\" : {\n      \"filter\" : [\"mixed/*\"]\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/otherPageobjects/otherPage.js",
    "content": "module.exports = {\n  url: '/other',\n  elements: {\n    myElement: {selector: '.myElement'}\n  }\n};\n"
  },
  {
    "path": "test/extra/package.json",
    "content": "{\n  \"name\": \"nightwatch\"\n}"
  },
  {
    "path": "test/extra/pageobjects/commands/commandsClassWithName.js",
    "content": "module.exports = class {\n\n  basicCommand() {\n    return {\n      basicResult: 'from-helper-class'\n    };\n  }\n\n  dropdownSelect() {\n    return this;\n  }\n\n  dropdownSelectByText() {\n    return this;\n  }\n\n  name() {\n    return this;\n  }\n\n};"
  },
  {
    "path": "test/extra/pageobjects/commands/common-commands.js",
    "content": "module.exports = {\n\n  dropdownSelect() {\n    return this;\n  },\n\n  dropdownSelectByText() {\n    return this;\n  },\n\n  scrollToElement() {\n    return this;\n  },\n\n  name() {\n    return this;\n  }\n};"
  },
  {
    "path": "test/extra/pageobjects/commands/helperCommandsClass.js",
    "content": "module.exports = class {\n\n  basicCommand() {\n    return {\n      basicResult: 'from-helper-class'\n    };\n  }\n\n  dropdownSelect() {\n    return this;\n  }\n\n  dropdownSelectByText() {\n    return this;\n  }\n\n  scrollToElement() {\n    return this;\n  }\n\n};"
  },
  {
    "path": "test/extra/pageobjects/commands/workingCommandsClass.js",
    "content": "module.exports = class RealCommands {\n\n  customFindElements(selector, callback = function(r) {return r}) {\n    return this.page.findElements({\n      selector,\n      suppressNotFoundErrors: true\n    }, function(result) {\n      return callback(result ? result.value : []);\n    });\n  }\n\n  async customFindElementsES6(selector) {\n    const result = await this.page.findElements({\n      selector,\n      suppressNotFoundErrors: true\n    });\n\n    return result;\n  }\n};"
  },
  {
    "path": "test/extra/pageobjects/pages/addl/simplePageObject.js",
    "content": "module.exports = {\n  elements: {}\n};\n"
  },
  {
    "path": "test/extra/pageobjects/pages/api/method/bar.js",
    "content": "module.exports = {\n  sections: {\n    bar: {\n      selector: '#bar'\n    }\n  }\n};\n"
  },
  {
    "path": "test/extra/pageobjects/pages/api/method/foo.js",
    "content": "module.exports = {\n  sections: {\n    foo: {\n      selector: '#foo'\n    }\n  }\n};\n"
  },
  {
    "path": "test/extra/pageobjects/pages/invalidPageObj.js",
    "content": "module.exports = {\n  sections: {\n    testSection: {\n      selector: '.section',\n      sections: {\n        testSubSection: {selector: '//[@class=\"el1\"]', locateStrategy: 'xpath'}\n      }\n    }\n  }\n};"
  },
  {
    "path": "test/extra/pageobjects/pages/pageObjElementsArray.js",
    "content": "module.exports = {\n  elements: [\n    {someElement: '#element'},\n    {otherElement: '#otherElement'}\n  ]\n};\n"
  },
  {
    "path": "test/extra/pageobjects/pages/simplePageObj.js",
    "content": "const testCommands = {\n  testCommand: function () {\n    this.api.elements('css selector', '#weblogin', res => {\n      this.clearValue('#weblogin');\n      this.perform(function() {});\n    });\n\n    return this;\n  }\n};\n\nmodule.exports = {\n  url: 'http://localhost.com',\n  elements: {\n    loginAsString: '#weblogin',\n    loginCss: {selector: '#weblogin'},\n    loginIndexed: {selector: '#weblogin', index: 1},\n    loginXpath: {selector: '//weblogin', locateStrategy: 'xpath'},\n    loginId: {selector: 'weblogin', locateStrategy: 'id'}\n  },\n  sections: {\n    signUp: {\n      selector: '#signupSection',\n      commands: {\n        sectionElements(cb) {\n          this.api.elements('css selector', '.btn', function(result) {\n            cb(result);\n          });\n        },\n        sectionElement(cb) {\n          this.api.element('css selector', '#helpBtn', function(result) {\n            cb(result);\n          });\n        }\n      },\n      sections: {\n        getStarted: {\n          selector: '#getStarted',\n          elements: {\n            start: {selector: '#getStartedStart'}\n          }\n        }\n      },\n      elements: {\n        help: {selector: '#helpBtn'}\n      }\n    },\n    propTest: {\n      selector: '#propTest',\n      props: function () {\n        const defaults = {};\n        defaults[this.name] = this.selector + ' Value';\n\n        return {\n          defaults\n        };\n      }\n    }\n  },\n  commands: [testCommands],\n  props: function () {\n    return {\n      prop: 'example',\n      url: this.url\n    };\n  }\n};\n"
  },
  {
    "path": "test/extra/pageobjects/pages/simplePageObjDefaultXpath.js",
    "content": "module.exports = {\n  url: 'http://localhost.com',\n  elements: {\n    xpathElement: '//div',\n    xpathElement2: {selector: '//div[@class=\"example\"]'},\n    cssSelectorElement: {\n      selector: '#weblogin',\n      locateStrategy: 'css selector'\n    }\n  },\n  sections: {\n    signUp: {\n      selector: '//div',\n      elements: {\n        start: {\n          selector: '#getStartedStart',\n          locateStrategy: 'css selector'\n        }\n      }\n    }\n  },\n  commands: []\n};\n"
  },
  {
    "path": "test/extra/pageobjects/pages/simplePageObjWithCommandsClass.js",
    "content": "const assert = require('assert');\nconst CommonCommands = require('../commands/helperCommandsClass.js');\n\nclass PageCommands extends CommonCommands {\n  constructor() {\n    super();\n\n    assert.strictEqual(this.api.sessionId, '1352110219202');\n    assert.strictEqual(this.browser.sessionId, '1352110219202');\n    assert.strictEqual(this.client.api.sessionId, '1352110219202');\n    assert.ok(this.transportActions);\n    assert.ok(this.driver);\n    assert.ok(this.section);\n    assert.ok(this.page);\n    assert.ok(typeof this.httpRequest == 'function');\n    assert.ok(typeof this.toString == 'function');\n  }\n\n  basicCommand() {\n    const basic = super.basicCommand();\n\n    return {\n      ...basic,\n      otherResult: 'from-other-helper-class'\n    };\n  }\n}\n\nmodule.exports = {\n  url: 'http://localhost.com',\n  elements: {\n    loginAsString: '#weblogin',\n    loginCss: {selector: '#weblogin'},\n    loginIndexed: {\n      selector: '#weblogin',\n      index: 1\n    },\n    loginXpath: {\n      selector: '//weblogin',\n      locateStrategy: 'xpath'\n    },\n    loginId: {\n      selector: 'weblogin',\n      locateStrategy: 'id'\n    }\n  },\n\n  commands: [PageCommands]\n};\n"
  },
  {
    "path": "test/extra/pageobjects/pages/simplePageObjWithCommandsClassThrowsError.js",
    "content": "const CommonCommands = require('../commands/commandsClassWithName.js');\n\nmodule.exports = {\n  url: 'http://localhost.com',\n  elements: {\n    loginAsString: '#weblogin',\n    loginCss: {selector: '#weblogin'},\n    loginIndexed: {\n      selector: '#weblogin',\n      index: 1\n    },\n    loginXpath: {\n      selector: '//weblogin',\n      locateStrategy: 'xpath'\n    },\n    loginId: {\n      selector: 'weblogin',\n      locateStrategy: 'id'\n    }\n  },\n\n  commands: CommonCommands\n};\n"
  },
  {
    "path": "test/extra/pageobjects/pages/simplePageObjWithCommandsObject.js",
    "content": "module.exports = {\n  url: 'http://localhost.com',\n  elements: {\n    loginAsString: '#weblogin',\n    loginCss: {selector: '#weblogin'},\n    loginIndexed: {\n      selector: '#weblogin',\n      index: 1\n    },\n    loginXpath: {\n      selector: '//weblogin',\n      locateStrategy: 'xpath'\n    },\n    loginId: {\n      selector: 'weblogin',\n      locateStrategy: 'id'\n    }\n  },\n  commands: {\n    dropdownSelect() {\n      return this;\n    },\n\n    dropdownSelectByText() {\n      return this;\n    },\n\n    scrollToElement() {\n      return this;\n    },\n\n    testCommand() {\n      return this;\n    }\n  }\n};\n"
  },
  {
    "path": "test/extra/pageobjects/pages/simplePageObjWithError.js",
    "content": "const commonCommands = require('../commands/common-commands.js');\n\nconst testCommands = {\n  ...commonCommands,\n\n  testCommand: function () {\n    this.api.elements('css selector', '#weblogin', res => {\n      this.clearValue('#weblogin');\n      this.perform(function() {\n      });\n    });\n\n    return this;\n  }\n};\n\nconst o = {\n  url: 'http://localhost.com',\n  elements: {\n    loginAsString: '#weblogin',\n    loginCss: {selector: '#weblogin'},\n    loginIndexed: {selector: '#weblogin', index: 1},\n    loginXpath: {selector: '//weblogin', locateStrategy: 'xpath'},\n    loginId: {selector: 'weblogin', locateStrategy: 'id'}\n  },\n  sections: {\n    signUp: {\n      selector: '#signupSection',\n      sections: {\n        getStarted: {\n          selector: '#getStarted',\n          elements: {\n            start: {selector: '#getStartedStart'}\n          }\n        }\n      },\n      elements: {\n        help: {selector: '#helpBtn'}\n      }\n    },\n    propTest: {\n      selector: '#propTest',\n      props: function () {\n        const defaults = {};\n        defaults[this.name] = this.selector + ' Value';\n\n        return {\n          defaults\n        };\n      }\n    }\n  },\n  commands: [testCommands],\n  props: function () {\n    return {\n      prop: 'example',\n      url: this.url\n    };\n  }\n};\n\nmodule.exports = o;"
  },
  {
    "path": "test/extra/pageobjects/pages/waitForElementNotPresentPageObj.js",
    "content": "module.exports = {\n  commands: [{\n    waitForElementNotPresentDemo(cb) {\n      this.click('@button')\n      const dialog = this.section.dialog;\n      dialog.selectValueDemo(cb)\n    }\n  }],\n  elements: {\n    button: '#weblogin'\n  },\n  sections: {\n    dialog: {\n      selector: '#weblogin',\n      elements: {\n        select: '#badElement'\n      },\n      commands: [{\n        selectValueDemo(cb) {\n          this.waitForElementNotPresent('@select', cb);\n        }\n      }]\n    }\n  }\n};\n"
  },
  {
    "path": "test/extra/pageobjects/pages/workingPageObjPlain.js",
    "content": "module.exports = {\n  commands: require('../commands/workingCommandsClass.js'),\n  url: 'http://localhost',\n\n  elements: {\n    loginAsString: '#weblogin'\n  },\n\n  props() {\n    return {\n      prop: 'example',\n      url: this.url\n    };\n  }\n};\n"
  },
  {
    "path": "test/extra/parallelism-auto.json",
    "content": "{\n  \"src_folders\" : [\"./test/sampletests/before-after\"],\n  \"output_folder\" : false,\n  \"test_workers\" : {\n    \"enabled\" : true,\n    \"workers\" : \"auto\"\n  },\n  \"output\" : false,\n  \"selenium\" : {\n    \"start_process\" : false\n  },\n\n  \"test_settings\": {\n    \"default\" : {\n      \"silent\" : true,\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      }\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/parallelism-count.json",
    "content": "{\n  \"src_folders\" : [\"./test/sampletests/before-after\"],\n  \"output_folder\" : false,\n  \"output\" : false,\n  \"test_workers\" : {\n    \"enabled\" : true,\n    \"workers\" : 6\n  },\n\n  \"selenium\" : {\n    \"start_process\" : false\n  },\n\n  \"test_settings\": {\n    \"default\" : {\n      \"silent\" : true,\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      }\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/parallelism-customCommandsSync.json",
    "content": "{\n  \"src_folders\" : [\"./test/apidemos/custom-commands-parallel\"],\n  \"test_workers\": true,\n  \"custom_commands_path\": [\"./test/extra/commands/other\"],\n  \"persist_globals\": true,\n  \"output_folder\" : false,\n  \"output\" : false,\n  \"silent\": false,\n  \"selenium\" : {\n    \"start_process\" : false,\n    \"port\": 10195\n  },\n  \"test_settings\": {\n    \"default\" : {\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/extra/parallelism-disabled.json",
    "content": "{\n  \"src_folders\" : [\"./test/sampletests\"],\n  \"output_folder\" : false,\n  \"test_workers\" : {\n    \"enabled\" : true,\n    \"workers\" : \"auto\"\n  },\n  \"output\" : false,\n  \"selenium\" : {\n    \"start_process\" : false\n  },\n\n  \"test_settings\": {\n    \"default\" : {\n      \"silent\" : true,\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      },\n      \"test_workers\" : false\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/parallelism-envs.json",
    "content": "{\n  \"src_folders\" : [\"./test/sampletests\"],\n  \"output_folder\" : false,\n  \"output\" : false,\n\n  \"selenium\" : {\n    \"start_process\" : false\n  },\n\n  \"test_settings\": {\n    \"default\" : {\n      \"silent\" : true,\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      }\n    },\n    \"env1\" : {\n      \"filter\" : \"mixed/*\"\n    },\n    \"env2\" : {\n      \"filter\" : \"simple/**\"\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/parallelism-execArgv-selected.json",
    "content": "{\n  \"src_folders\" : [\"./test/sampletests\"],\n  \"output_folder\" : false,\n  \"test_workers\" : {\n    \"enabled\": true,\n    \"node_options\": [\"--harmony\"]\n  },\n  \"output\" : false,\n  \"selenium\" : {\n    \"start_process\" : false\n  },\n\n  \"test_settings\": {\n    \"default\" : {\n      \"silent\" : true,\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      }\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/parallelism-execArgv.json",
    "content": "{\n  \"src_folders\" : [\"./test/sampletests\"],\n  \"output_folder\" : false,\n  \"test_workers\" : {\n    \"enabled\": true,\n    \"node_options\": \"inherit\"\n  },\n  \"output\" : false,\n  \"selenium\" : {\n    \"start_process\" : false\n  },\n\n  \"test_settings\": {\n    \"default\" : {\n      \"silent\" : true,\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      }\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/parallelism-selenium-server.json",
    "content": "{\n  \"src_folders\" : [\"./test/sampletests/before-after\"],\n  \"output_folder\" : false,\n  \"test_workers\" : {\n    \"enabled\" : true,\n    \"workers\" : 2\n  },\n  \"output\" : false,\n  \"selenium\" : {\n    \"start_process\" : true\n  },\n\n  \"test_settings\": {\n    \"default\" : {\n      \"silent\" : true,\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      }\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/parallelism-workers.conf.js",
    "content": "module.exports = {\n  src_folders: ['./test/sampletests'],\n  output_folder: false,\n  output: true,\n  webdriver: {\n    keep_alive: true\n  },\n\n  test_settings: {\n    default: {\n      silent: false,\n      test_workers: {\n        enabled: true,\n        workers: 5\n      },\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      webdriver: {\n        start_process: true,\n        server_path: ''\n      }\n    },\n    selenium_server: {\n      selenium: {\n        start_process: false,\n        host: '127.0.0.1'\n      }\n    },\n\n    chrome: {\n      extends: 'selenium_server',\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    }\n  }\n};\n\n\n"
  },
  {
    "path": "test/extra/parallelism.json",
    "content": "{\n  \"src_folders\" : [\"./test/sampletests/before-after\"],\n  \"output_folder\" : false,\n  \"test_workers\" : true,\n  \"output\" : false,\n  \"selenium\" : {\n    \"start_process\" : false\n  },\n\n  \"test_settings\": {\n    \"default\" : {\n      \"silent\" : true,\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      }\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/plugin/index.js",
    "content": ""
  },
  {
    "path": "test/extra/plugin/nightwatch/assertions/customAssertion.js",
    "content": "exports.assertion = function(definition, expectedTxt, msg) {\n  //Nightwatch custom assertion\n};"
  },
  {
    "path": "test/extra/plugin/nightwatch/commands/customCommand.js",
    "content": "module.exports = class CustomCommand {\n  command() {\n    // Nightwatch custom command\n  }\n};"
  },
  {
    "path": "test/extra/plugin/nightwatch/globals.js",
    "content": "module.exports = {\n  reporter(results, done) {\n    this.reporterCount++;\n    done();\n  }\n};"
  },
  {
    "path": "test/extra/reportObject.js",
    "content": "module.exports = {\n  passed: 40,\n  failed: 3,\n  errors: 0,\n  skipped: 2,\n  tests: 0,\n  assertions: 43,\n  errmessages: [\n  ],\n  modules: {\n    selectElement: {\n      reportPrefix: 'FIREFOX_111.0.1__',\n      assertionsCount: 1,\n      lastError: null,\n      skippedAtRuntime: [\n      ],\n      skipped: [\n      ],\n      time: '1.082',\n      timeMs: 1082,\n      completed: {\n        demoTest: {\n          time: '1.082',\n          assertions: [\n            {\n              name: 'NightwatchAssertError',\n              message: 'Forth option is selected (4ms)',\n              stackTrace: '',\n              fullMsg: 'Forth option is selected \\u001b[0;90m(4ms)\\u001b[0m',\n              failure: false\n            }\n          ],\n          commands: [\n          ],\n          passed: 1,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 1,\n          status: 'pass',\n          steps: [\n          ],\n          stackTrace: '',\n          testcases: {\n            demoTest: {\n              time: '1.082',\n              assertions: [\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Forth option is selected \\u001b[0;90m(4ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Forth option is selected \\u001b[0;90m(4ms)\\u001b[0m',\n                  failure: false\n                }\n              ],\n              tests: 1,\n              commands: [\n              ],\n              passed: 1,\n              errors: 0,\n              failed: 0,\n              skipped: 0,\n              status: 'pass',\n              steps: [\n              ],\n              stackTrace: '',\n              timeMs: 1082,\n              startTimestamp: 'Thu, 06 Apr 2023 10:19:41 GMT',\n              endTimestamp: 'Thu, 06 Apr 2023 10:19:42 GMT'\n            }\n          },\n          timeMs: 1082,\n          startTimestamp: 'Thu, 06 Apr 2023 10:19:41 GMT',\n          endTimestamp: 'Thu, 06 Apr 2023 10:19:42 GMT'\n        }\n      },\n      completedSections: {\n        __global_beforeEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __before_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        demoTest: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'url',\n              args: [\n                'https://www.selenium.dev/selenium/web/formPage.html'\n              ],\n              startTime: 1680776381835,\n              endTime: 1680776382638,\n              elapsedTime: 803,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'element().getAttribute',\n              args: [\n                'tagName'\n              ],\n              startTime: 1680776382642,\n              endTime: 1680776382669,\n              elapsedTime: 27,\n              status: 'pass',\n              result: {\n              }\n            },\n            {\n              name: 'element().findElement',\n              args: [\n                '[object Object]'\n              ],\n              startTime: 1680776382669,\n              endTime: 1680776382674,\n              elapsedTime: 5,\n              status: 'pass',\n              result: {\n              }\n            },\n            {\n              name: 'perform',\n              args: [\n                'function () { [native code] }'\n              ],\n              startTime: 1680776382639,\n              endTime: 1680776382900,\n              elapsedTime: 261,\n              status: 'pass'\n            },\n            {\n              name: 'element().findElement',\n              args: [\n                '[object Object]'\n              ],\n              startTime: 1680776382901,\n              endTime: 1680776382905,\n              elapsedTime: 4,\n              status: 'pass',\n              result: {\n              }\n            },\n            {\n              name: 'assert.selected',\n              args: [\n                '[object Object]',\n                'Forth option is selected'\n              ],\n              startTime: 1680776382906,\n              endTime: 1680776382912,\n              elapsedTime: 6,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __after_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __global_afterEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'end',\n              args: [\n                'true'\n              ],\n              startTime: 1680776382919,\n              endTime: 1680776384029,\n              elapsedTime: 1110,\n              status: 'pass'\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        }\n      },\n      errmessages: [\n      ],\n      testsCount: 1,\n      skippedCount: 0,\n      failedCount: 0,\n      errorsCount: 0,\n      passedCount: 1,\n      group: '',\n      modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/selectElement.js',\n      startTimestamp: 'Thu, 06 Apr 2023 10:19:40 GMT',\n      endTimestamp: 'Thu, 06 Apr 2023 10:19:42 GMT',\n      sessionCapabilities: {\n        acceptInsecureCerts: false,\n        browserName: 'firefox',\n        browserVersion: '111.0.1',\n        'moz:accessibilityChecks': false,\n        'moz:buildID': '20230321111920',\n        'moz:geckodriverVersion': '0.32.0',\n        'moz:headless': false,\n        'moz:platformVersion': '22.3.0',\n        'moz:processID': 93822,\n        'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileHW3NPW',\n        'moz:shutdownTimeout': 60000,\n        'moz:useNonSpecCompliantPointerOrigin': false,\n        'moz:webdriverClick': true,\n        'moz:windowless': false,\n        pageLoadStrategy: 'normal',\n        platformName: 'mac',\n        proxy: {\n        },\n        setWindowRect: true,\n        strictFileInteractability: false,\n        timeouts: {\n          implicit: 0,\n          pageLoad: 300000,\n          script: 30000\n        },\n        unhandledPromptBehavior: 'dismiss and notify'\n      },\n      sessionId: 'a1f5ad5e-07f5-4800-ba12-b7a271e609a9',\n      projectName: '',\n      buildName: '',\n      testEnv: 'firefox',\n      isMobile: false,\n      status: 'pass',\n      seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/selectElement_geckodriver.log',\n      host: 'localhost',\n      tests: 1,\n      failures: 0,\n      errors: 0,\n      httpOutput: [\n        [\n          '2023-04-06T10:19:40.629Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:41.827Z',\n          '  Response 200 POST /session (1199ms)',\n          '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;a1f5ad5e-07f5-4800-ba12-b7a271e609a9&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93822<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileHW3NPW&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:41.837Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/url  </span></b>',\n          '{ url: <span style=\"color:#0A0\">&#39;https://www.selenium.dev/selenium/web/formPage.html&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.638Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/url (801ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:42.643Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;select[name=selectomatic]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.660Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/elements (17ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ab344c02-89da-455d-a6d9-f3d066201c38&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.661Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var h=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=h;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (43188 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ab344c02-89da-455d-a6d9-f3d066201c38&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;ab344c02-89da-455d-a6d9-f3d066201c38&#39;<span style=\"color:#FFF\">\\n       },\\n       <span style=\"color:#0A0\">&#39;tagName&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.668Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/execute/sync (7ms)',\n          '{ value: <span style=\"color:#0A0\">&#39;SELECT&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.670Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;xpath&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;./option[. = &quot;Four&quot;]|./option[normalize-space(text()) = &quot;Four&quot;]|./optgroup/option[. = &quot;Four&quot;]|./optgroup/option[normalize-space(text()) = &quot;Four&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.674Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element (4ms)',\n          '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f5aa1430-b88f-46cf-9816-c48c2ef74bfd&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.675Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.678Z',\n          '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected (3ms)',\n          '{ value: <span style=\"color:#A50\">false<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.679Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/enabled  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.687Z',\n          '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/enabled (9ms)',\n          '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.688Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/click  </span></b>',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:19:42.900Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/click (212ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:42.901Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;option[value=four]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.905Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element (4ms)',\n          '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f5aa1430-b88f-46cf-9816-c48c2ef74bfd&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.909Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.911Z',\n          '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected (3ms)',\n          '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.921Z',\n          '  Request <b><span style=\"color:#0AA\">DELETE /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.026Z',\n          '  Response 200 DELETE /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9 (1105ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ]\n      ],\n      rawHttpOutput: [\n        [\n          '2023-04-06T10:19:40.629Z',\n          '  Request POST /session  ',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:41.827Z',\n          '  Response 200 POST /session (1199ms)',\n          '{\\n     value: {\\n       sessionId: \\'a1f5ad5e-07f5-4800-ba12-b7a271e609a9\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93822,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileHW3NPW\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:41.837Z',\n          '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/url  ',\n          '{ url: \\'https://www.selenium.dev/selenium/web/formPage.html\\' }'\n        ],\n        [\n          '2023-04-06T10:19:42.638Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/url (801ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:42.643Z',\n          '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/elements  ',\n          '{ using: \\'css selector\\', value: \\'select[name=selectomatic]\\' }'\n        ],\n        [\n          '2023-04-06T10:19:42.660Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/elements (17ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ab344c02-89da-455d-a6d9-f3d066201c38\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:42.661Z',\n          '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var h=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=h;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (43188 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ab344c02-89da-455d-a6d9-f3d066201c38\\',\\n         ELEMENT: \\'ab344c02-89da-455d-a6d9-f3d066201c38\\'\\n       },\\n       \\'tagName\\'\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:42.668Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/execute/sync (7ms)',\n          '{ value: \\'SELECT\\' }'\n        ],\n        [\n          '2023-04-06T10:19:42.670Z',\n          '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element  ',\n          '{\\n     using: \\'xpath\\',\\n     value: \\'./option[. = &quot;Four&quot;]|./option[normalize-space(text()) = &quot;Four&quot;]|./optgroup/option[. = &quot;Four&quot;]|./optgroup/option[normalize-space(text()) = &quot;Four&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:42.674Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element (4ms)',\n          '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f5aa1430-b88f-46cf-9816-c48c2ef74bfd\\'\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:42.675Z',\n          '  Request GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:42.678Z',\n          '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected (3ms)',\n          '{ value: false }'\n        ],\n        [\n          '2023-04-06T10:19:42.679Z',\n          '  Request GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/enabled  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:42.687Z',\n          '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/enabled (9ms)',\n          '{ value: true }'\n        ],\n        [\n          '2023-04-06T10:19:42.688Z',\n          '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/click  ',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:19:42.900Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/click (212ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:42.901Z',\n          '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element  ',\n          '{ using: \\'css selector\\', value: \\'option[value=four]\\' }'\n        ],\n        [\n          '2023-04-06T10:19:42.905Z',\n          '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element (4ms)',\n          '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f5aa1430-b88f-46cf-9816-c48c2ef74bfd\\'\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:42.909Z',\n          '  Request GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:42.911Z',\n          '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected (3ms)',\n          '{ value: true }'\n        ],\n        [\n          '2023-04-06T10:19:42.921Z',\n          '  Request DELETE /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:44.026Z',\n          '  Response 200 DELETE /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9 (1105ms)',\n          '{ value: null }'\n        ]\n      ]\n    },\n    chromeCDP_example: {\n      reportPrefix: 'FIREFOX_111.0.1__',\n      assertionsCount: 1,\n      lastError: {\n        name: 'NightwatchAssertError',\n        message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n        showDiff: false,\n        abortOnFailure: true,\n        stack: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)'\n      },\n      skippedAtRuntime: [\n      ],\n      skipped: [\n      ],\n      time: '4.669',\n      timeMs: 4669,\n      completed: {\n        'using CDP DOM Snapshot': {\n          time: '4.669',\n          assertions: [\n            {\n              name: 'NightwatchAssertError',\n              message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \"documents,strings\" but got: \"abortOnFailure\" (4ms)',\n              stackTrace: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)',\n              fullMsg: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n              failure: 'Expected \"documents,strings\" but got: \"abortOnFailure\"',\n              screenshots: [\n                '/Users/vaibhavsingh/Dev/nightwatch/screens/chromeCDP_example/using-CDP-DOM-Snapshot_FAILED_Apr-06-2023-154931-GMT+0530.png'\n              ]\n            }\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 1,\n          skipped: 0,\n          tests: 1,\n          status: 'fail',\n          steps: [\n          ],\n          stackTrace: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)',\n          testcases: {\n            'using CDP DOM Snapshot': {\n              time: '4.669',\n              assertions: [\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n                  stackTrace: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)',\n                  fullMsg: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n                  failure: 'Expected \"documents,strings\" but got: \"abortOnFailure\"',\n                  screenshots: [\n                    '/Users/vaibhavsingh/Dev/nightwatch/screens/chromeCDP_example/using-CDP-DOM-Snapshot_FAILED_Apr-06-2023-154931-GMT+0530.png'\n                  ]\n                }\n              ],\n              tests: 1,\n              commands: [\n              ],\n              passed: 0,\n              errors: 0,\n              failed: 1,\n              skipped: 0,\n              status: 'fail',\n              steps: [\n              ],\n              stackTrace: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)',\n              lastError: {\n                name: 'NightwatchAssertError',\n                message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n                showDiff: false,\n                abortOnFailure: true,\n                stack: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)'\n              },\n              timeMs: 4669,\n              startTimestamp: 'Thu, 06 Apr 2023 10:19:27 GMT',\n              endTimestamp: 'Thu, 06 Apr 2023 10:19:32 GMT'\n            }\n          },\n          lastError: {\n            name: 'NightwatchAssertError',\n            message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n            showDiff: false,\n            abortOnFailure: true,\n            stack: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)'\n          },\n          timeMs: 4669,\n          startTimestamp: 'Thu, 06 Apr 2023 10:19:27 GMT',\n          endTimestamp: 'Thu, 06 Apr 2023 10:19:32 GMT'\n        }\n      },\n      completedSections: {\n        __global_beforeEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __before_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        'using CDP DOM Snapshot': {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'navigateTo',\n              args: [\n                'https://nightwatchjs.org'\n              ],\n              startTime: 1680776367423,\n              endTime: 1680776371918,\n              elapsedTime: 4495,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'chrome.sendAndGetDevToolsCommand',\n              args: [\n                'DOMSnapshot.captureSnapshot',\n                '[object Object]'\n              ],\n              startTime: 1680776371920,\n              endTime: 1680776371920,\n              elapsedTime: 0,\n              status: 'fail',\n              result: {\n                message: 'Error while running \"chrome.sendAndGetDevToolsCommand\" command: [TypeError] nightwatchInstance.transport.driver[commandName] is not a function',\n                name: 'TypeError',\n                abortOnFailure: true,\n                stack: 'TypeError: Error while running \"chrome.sendAndGetDevToolsCommand\" command: [TypeError] nightwatchInstance.transport.driver[commandName] is not a function\\n    at ChromeCommandLoader.commandFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/_base-loader.js:38:62)\\n    at TreeNode.invokeCommand (/Users/vaibhavsingh/Dev/nightwatch/lib/core/treenode.js:154:31)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/core/treenode.js:177:12\\n    at new Promise (<anonymous>)\\n    at TreeNode.execute (/Users/vaibhavsingh/Dev/nightwatch/lib/core/treenode.js:176:12)\\n    at TreeNode.runCommand (/Users/vaibhavsingh/Dev/nightwatch/lib/core/treenode.js:138:27)\\n    at TreeNode.run (/Users/vaibhavsingh/Dev/nightwatch/lib/core/treenode.js:112:17)\\n    at AsyncTree.runChildNode (/Users/vaibhavsingh/Dev/nightwatch/lib/core/asynctree.js:118:31)\\n    at AsyncTree.traverse (/Users/vaibhavsingh/Dev/nightwatch/lib/core/asynctree.js:48:33)\\n    at CommandQueue.traverse (/Users/vaibhavsingh/Dev/nightwatch/lib/core/queue.js:97:8)',\n                beautifiedStack: {\n                  filePath: '/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/_base-loader.js',\n                  error_line_number: 38,\n                  codeSnippet: [\n                    {\n                      line_number: 36,\n                      code: '  static createDriverCommand(nightwatchInstance, commandName) {'\n                    },\n                    {\n                      line_number: 37,\n                      code: '    return function commandFn({args}) {'\n                    },\n                    {\n                      line_number: 38,\n                      code: '      return nightwatchInstance.transport.driver[commandName](...args).catch((error) => {'\n                    },\n                    {\n                      line_number: 39,\n                      code: '        if (error.remoteStacktrace) {'\n                    },\n                    {\n                      line_number: 40,\n                      code: '          delete error.remoteStacktrace;'\n                    }\n                  ]\n                }\n              }\n            },\n            {\n              name: 'assert.deepStrictEqual',\n              args: [\n              ],\n              startTime: 1680776371927,\n              endTime: 1680776371930,\n              elapsedTime: 3,\n              status: 'fail',\n              result: {\n                message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \"documents,strings\" but got: \"abortOnFailure\" (4ms)',\n                showDiff: false,\n                name: 'NightwatchAssertError',\n                abortOnFailure: true,\n                stack: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)',\n                beautifiedStack: {\n                  filePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js',\n                  error_line_number: 10,\n                  codeSnippet: [\n                    {\n                      line_number: 8,\n                      code: '    });'\n                    },\n                    {\n                      line_number: 9,\n                      code: ''\n                    },\n                    {\n                      line_number: 10,\n                      code: '    browser.assert.deepStrictEqual(Object.keys(dom), [\\'documents\\', \\'strings\\']);'\n                    },\n                    {\n                      line_number: 11,\n                      code: '  });'\n                    },\n                    {\n                      line_number: 12,\n                      code: '});'\n                    }\n                  ]\n                }\n              },\n              screenshot: '/Users/vaibhavsingh/Dev/nightwatch/screens/chromeCDP_example/using-CDP-DOM-Snapshot_FAILED_Apr-06-2023-154931-GMT+0530.png'\n            },\n            {\n              name: 'saveScreenshot',\n              args: [\n                '/Users/vaibhavsingh/Dev/nightwatch/screens/chromeCDP_example/using-CDP-DOM-Snapshot_FAILED_Apr-06-2023-154931-GMT+0530.png',\n                'function () { [native code] }'\n              ],\n              startTime: 1680776371985,\n              endTime: 1680776372089,\n              elapsedTime: 104,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'fail'\n        },\n        __after_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __global_afterEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'end',\n              args: [\n                'true'\n              ],\n              startTime: 1680776372096,\n              endTime: 1680776372556,\n              elapsedTime: 460,\n              status: 'pass'\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        }\n      },\n      errmessages: [\n      ],\n      testsCount: 1,\n      skippedCount: 0,\n      failedCount: 1,\n      errorsCount: 0,\n      passedCount: 0,\n      group: '',\n      modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js',\n      startTimestamp: 'Thu, 06 Apr 2023 10:19:25 GMT',\n      endTimestamp: 'Thu, 06 Apr 2023 10:19:32 GMT',\n      sessionCapabilities: {\n        acceptInsecureCerts: false,\n        browserName: 'firefox',\n        browserVersion: '111.0.1',\n        'moz:accessibilityChecks': false,\n        'moz:buildID': '20230321111920',\n        'moz:geckodriverVersion': '0.32.0',\n        'moz:headless': false,\n        'moz:platformVersion': '22.3.0',\n        'moz:processID': 93704,\n        'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofiletwZmUW',\n        'moz:shutdownTimeout': 60000,\n        'moz:useNonSpecCompliantPointerOrigin': false,\n        'moz:webdriverClick': true,\n        'moz:windowless': false,\n        pageLoadStrategy: 'normal',\n        platformName: 'mac',\n        proxy: {\n        },\n        setWindowRect: true,\n        strictFileInteractability: false,\n        timeouts: {\n          implicit: 0,\n          pageLoad: 300000,\n          script: 30000\n        },\n        unhandledPromptBehavior: 'dismiss and notify'\n      },\n      sessionId: '245b46ac-127c-49fa-8360-05e674967894',\n      projectName: '',\n      buildName: '',\n      testEnv: 'firefox',\n      isMobile: false,\n      status: 'fail',\n      seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/chromeCDP_example_geckodriver.log',\n      host: 'localhost',\n      tests: 1,\n      failures: 1,\n      errors: 0,\n      httpOutput: [\n        [\n          '2023-04-06T10:19:25.786Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:27.415Z',\n          '  Response 200 POST /session (1630ms)',\n          '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;245b46ac-127c-49fa-8360-05e674967894&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93704<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofiletwZmUW&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:27.426Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/245b46ac-127c-49fa-8360-05e674967894/url  </span></b>',\n          '{ url: <span style=\"color:#0A0\">&#39;https://nightwatchjs.org&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:31.915Z',\n          '  Response 200 POST /session/245b46ac-127c-49fa-8360-05e674967894/url (4490ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:31.987Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/245b46ac-127c-49fa-8360-05e674967894/screenshot  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:32.085Z',\n          '  Response 200 GET /session/245b46ac-127c-49fa-8360-05e674967894/screenshot (76ms)',\n          '{\\n     value: <span style=\"color:#0A0\">&#39;iVBORw0KGgoAAAANSUhEUgAACgAAAAV8CAYAAAD3/MaLAAAgAElEQVR4XuydB3wURRvG34QUQu8gXQRpoqIiVhQUBQSxgYgF+RRB...&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:32.100Z',\n          '  Request <b><span style=\"color:#0AA\">DELETE /session/245b46ac-127c-49fa-8360-05e674967894  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:32.554Z',\n          '  Response 200 DELETE /session/245b46ac-127c-49fa-8360-05e674967894 (454ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ]\n      ],\n      rawHttpOutput: [\n        [\n          '2023-04-06T10:19:25.786Z',\n          '  Request POST /session  ',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:27.415Z',\n          '  Response 200 POST /session (1630ms)',\n          '{\\n     value: {\\n       sessionId: \\'245b46ac-127c-49fa-8360-05e674967894\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93704,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofiletwZmUW\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:27.426Z',\n          '  Request POST /session/245b46ac-127c-49fa-8360-05e674967894/url  ',\n          '{ url: \\'https://nightwatchjs.org\\' }'\n        ],\n        [\n          '2023-04-06T10:19:31.915Z',\n          '  Response 200 POST /session/245b46ac-127c-49fa-8360-05e674967894/url (4490ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:31.987Z',\n          '  Request GET /session/245b46ac-127c-49fa-8360-05e674967894/screenshot  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:32.085Z',\n          '  Response 200 GET /session/245b46ac-127c-49fa-8360-05e674967894/screenshot (76ms)',\n          '{\\n     value: \\'iVBORw0KGgoAAAANSUhEUgAACgAAAAV8CAYAAAD3/MaLAAAgAElEQVR4XuydB3wURRvG34QUQu8gXQRpoqIiVhQUBQSxgYgF+RRB...\\',\\n     suppressBase64Data: true\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:32.100Z',\n          '  Request DELETE /session/245b46ac-127c-49fa-8360-05e674967894  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:32.554Z',\n          '  Response 200 DELETE /session/245b46ac-127c-49fa-8360-05e674967894 (454ms)',\n          '{ value: null }'\n        ]\n      ],\n      globalErrorRegister: [\n        '   \\u001b[1;31m→ ✖ \\u001b[1;31mNightwatchAssertError\\u001b[0m\\n   \\u001b[0;31mFailed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m\\u001b[0m\\n\\u001b[0;33m\\n    Error location:\\u001b[0m\\n    /Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:\\n    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––\\n     8 |     });\\n     9 | \\n    \\u001b[0;37m\\u001b[41m 10 |     browser.assert.deepStrictEqual(Object.keys(dom), [\\'documents\\', \\'strings\\']); \\u001b[0m\\n     11 |   });\\n     12 | });\\n    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––\\n\\u001b[0m'\n      ]\n    },\n    angularTodoTest: {\n      reportPrefix: 'FIREFOX_111.0.1__',\n      assertionsCount: 2,\n      lastError: null,\n      skippedAtRuntime: [\n      ],\n      skipped: [\n      ],\n      time: '1.908',\n      timeMs: 1908,\n      completed: {\n        'should add a todo using custom commands': {\n          time: '1.908',\n          assertions: [\n            {\n              name: 'NightwatchAssertError',\n              message: 'Expected element <web element{f201c631-099d-4556-b725-1b9036ff21e7}> text to equal: \"what is nightwatch?\" (15ms)',\n              stackTrace: '',\n              fullMsg: 'Expected element <web element{f201c631-099d-4556-b725-1b9036ff21e7}> text to equal: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \"2\" (5ms)',\n              stackTrace: '',\n              fullMsg: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \\u001b[0;33m\"2\"\\u001b[0m\\u001b[0;90m (5ms)\\u001b[0m',\n              failure: false\n            }\n          ],\n          commands: [\n          ],\n          passed: 2,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 2,\n          status: 'pass',\n          steps: [\n          ],\n          stackTrace: '',\n          testcases: {\n            'should add a todo using custom commands': {\n              time: '1.908',\n              assertions: [\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Expected element <web element{f201c631-099d-4556-b725-1b9036ff21e7}> text to equal: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Expected element <web element{f201c631-099d-4556-b725-1b9036ff21e7}> text to equal: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \\u001b[0;33m\"2\"\\u001b[0m\\u001b[0;90m (5ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \\u001b[0;33m\"2\"\\u001b[0m\\u001b[0;90m (5ms)\\u001b[0m',\n                  failure: false\n                }\n              ],\n              tests: 2,\n              commands: [\n              ],\n              passed: 2,\n              errors: 0,\n              failed: 0,\n              skipped: 0,\n              status: 'pass',\n              steps: [\n              ],\n              stackTrace: '',\n              timeMs: 1908,\n              startTimestamp: 'Thu, 06 Apr 2023 10:19:27 GMT',\n              endTimestamp: 'Thu, 06 Apr 2023 10:19:29 GMT'\n            }\n          },\n          timeMs: 1908,\n          startTimestamp: 'Thu, 06 Apr 2023 10:19:27 GMT',\n          endTimestamp: 'Thu, 06 Apr 2023 10:19:29 GMT'\n        }\n      },\n      completedSections: {\n        __global_beforeEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __before_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        'should add a todo using custom commands': {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'navigateTo',\n              args: [\n                'https://angularjs.org'\n              ],\n              startTime: 1680776367982,\n              endTime: 1680776369381,\n              elapsedTime: 1399,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'sendKeys',\n              args: [\n                '[ng-model=\"todoList.todoText\"]',\n                'what is nightwatch?'\n              ],\n              startTime: 1680776369382,\n              endTime: 1680776369412,\n              elapsedTime: 30,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'click',\n              args: [\n                '[value=\"add\"]'\n              ],\n              startTime: 1680776369412,\n              endTime: 1680776369631,\n              elapsedTime: 219,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'getElementsInList',\n              args: [\n                'todoList.todos'\n              ],\n              startTime: 1680776369631,\n              endTime: 1680776369638,\n              elapsedTime: 7,\n              status: 'pass',\n              result: {\n              }\n            },\n            {\n              name: 'expect.element',\n              args: [\n                'web element{f201c631-099d-4556-b725-1b9036ff21e7}'\n              ],\n              startTime: 1680776369642,\n              endTime: 1680776369658,\n              elapsedTime: 16,\n              status: 'pass',\n              result: {\n              }\n            },\n            {\n              name: 'element().findElement',\n              args: [\n                '[object Object]'\n              ],\n              startTime: 1680776369658,\n              endTime: 1680776369662,\n              elapsedTime: 4,\n              status: 'pass',\n              result: {\n              }\n            },\n            {\n              name: 'click',\n              args: [\n                '[object Object]'\n              ],\n              startTime: 1680776369662,\n              endTime: 1680776369876,\n              elapsedTime: 214,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'expect.elements',\n              args: [\n                '*[module=todoApp] li .done-true'\n              ],\n              startTime: 1680776369878,\n              endTime: 1680776369883,\n              elapsedTime: 5,\n              status: 'pass',\n              result: {\n              }\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __after_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __global_afterEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'end',\n              args: [\n                'true'\n              ],\n              startTime: 1680776369890,\n              endTime: 1680776370259,\n              elapsedTime: 369,\n              status: 'pass'\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        }\n      },\n      errmessages: [\n      ],\n      testsCount: 1,\n      skippedCount: 0,\n      failedCount: 0,\n      errorsCount: 0,\n      passedCount: 2,\n      group: '',\n      modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/angularTodoTest.js',\n      startTimestamp: 'Thu, 06 Apr 2023 10:19:25 GMT',\n      endTimestamp: 'Thu, 06 Apr 2023 10:19:29 GMT',\n      sessionCapabilities: {\n        acceptInsecureCerts: false,\n        browserName: 'firefox',\n        browserVersion: '111.0.1',\n        'moz:accessibilityChecks': false,\n        'moz:buildID': '20230321111920',\n        'moz:geckodriverVersion': '0.32.0',\n        'moz:headless': false,\n        'moz:platformVersion': '22.3.0',\n        'moz:processID': 93705,\n        'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileCfAJtT',\n        'moz:shutdownTimeout': 60000,\n        'moz:useNonSpecCompliantPointerOrigin': false,\n        'moz:webdriverClick': true,\n        'moz:windowless': false,\n        pageLoadStrategy: 'normal',\n        platformName: 'mac',\n        proxy: {\n        },\n        setWindowRect: true,\n        strictFileInteractability: false,\n        timeouts: {\n          implicit: 0,\n          pageLoad: 300000,\n          script: 30000\n        },\n        unhandledPromptBehavior: 'dismiss and notify'\n      },\n      sessionId: '1a5fbc5c-7381-4c6e-991b-936453257b8d',\n      projectName: '',\n      buildName: '',\n      testEnv: 'firefox',\n      isMobile: false,\n      status: 'pass',\n      seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/angularTodoTest_geckodriver.log',\n      host: 'localhost',\n      tests: 1,\n      failures: 0,\n      errors: 0,\n      httpOutput: [\n        [\n          '2023-04-06T10:19:25.817Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:27.970Z',\n          '  Response 200 POST /session (2155ms)',\n          '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;1a5fbc5c-7381-4c6e-991b-936453257b8d&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93705<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileCfAJtT&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:27.986Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/url  </span></b>',\n          '{ url: <span style=\"color:#0A0\">&#39;https://angularjs.org&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.380Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/url (1394ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:29.385Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[ng-model=&quot;todoList.todoText&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.391Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (7ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9e5ff74b-5b5b-4221-90b6-d14dcc856ec8&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.393Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/9e5ff74b-5b5b-4221-90b6-d14dcc856ec8/value  </span></b>',\n          '{\\n     text: <span style=\"color:#0A0\">&#39;what is nightwatch?&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;n&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;?&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.411Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/9e5ff74b-5b5b-4221-90b6-d14dcc856ec8/value (18ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:29.413Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[value=&quot;add&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.416Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (3ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;b00c28b3-319c-44f5-906d-c24b3debafd7&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.418Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/b00c28b3-319c-44f5-906d-c24b3debafd7/click  </span></b>',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:19:29.631Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/b00c28b3-319c-44f5-906d-c24b3debafd7/click (213ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:29.634Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;var passedArgs = Array.prototype.slice.call(arguments,0); return (function(listName) {\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;      // executed in the browser context\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;      // eslint-disable-next-line\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;      var elements = document.querySel... (366 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [ <span style=\"color:#0A0\">&#39;todoList.todos&#39;<span style=\"color:#FFF\"> ]\\n  }</span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.637Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/execute/sync (3ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;df85178f-1166-489c-827d-17e13fecf95a&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ed6dc16b-f99b-4ab7-821b-c17030dcd5de&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f201c631-099d-4556-b725-1b9036ff21e7&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.643Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/text  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.656Z',\n          '  Response 200 GET /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/text (13ms)',\n          '{ value: <span style=\"color:#0A0\">&#39;what is nightwatch?&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.659Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/element  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.662Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/element (3ms)',\n          '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;8b05c802-195a-4804-a216-09892ca94a68&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.663Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/8b05c802-195a-4804-a216-09892ca94a68/click  </span></b>',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:19:29.875Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/8b05c802-195a-4804-a216-09892ca94a68/click (212ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:29.879Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;*[module=todoApp] li .done-true&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.883Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (4ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f027fd19-1bf0-406e-899c-c005c1e40456&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ed3f1754-6119-41a2-83c1-d56075d6b38a&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.893Z',\n          '  Request <b><span style=\"color:#0AA\">DELETE /session/1a5fbc5c-7381-4c6e-991b-936453257b8d  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:30.257Z',\n          '  Response 200 DELETE /session/1a5fbc5c-7381-4c6e-991b-936453257b8d (365ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ]\n      ],\n      rawHttpOutput: [\n        [\n          '2023-04-06T10:19:25.817Z',\n          '  Request POST /session  ',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:27.970Z',\n          '  Response 200 POST /session (2155ms)',\n          '{\\n     value: {\\n       sessionId: \\'1a5fbc5c-7381-4c6e-991b-936453257b8d\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93705,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileCfAJtT\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:27.986Z',\n          '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/url  ',\n          '{ url: \\'https://angularjs.org\\' }'\n        ],\n        [\n          '2023-04-06T10:19:29.380Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/url (1394ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:29.385Z',\n          '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  ',\n          '{ using: \\'css selector\\', value: \\'[ng-model=&quot;todoList.todoText&quot;]\\' }'\n        ],\n        [\n          '2023-04-06T10:19:29.391Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (7ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9e5ff74b-5b5b-4221-90b6-d14dcc856ec8\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:29.393Z',\n          '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/9e5ff74b-5b5b-4221-90b6-d14dcc856ec8/value  ',\n          '{\\n     text: \\'what is nightwatch?\\',\\n     value: [\\n       \\'w\\', \\'h\\', \\'a\\', \\'t\\', \\' \\',\\n       \\'i\\', \\'s\\', \\' \\', \\'n\\', \\'i\\',\\n       \\'g\\', \\'h\\', \\'t\\', \\'w\\', \\'a\\',\\n       \\'t\\', \\'c\\', \\'h\\', \\'?\\'\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:29.411Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/9e5ff74b-5b5b-4221-90b6-d14dcc856ec8/value (18ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:29.413Z',\n          '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  ',\n          '{ using: \\'css selector\\', value: \\'[value=&quot;add&quot;]\\' }'\n        ],\n        [\n          '2023-04-06T10:19:29.416Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (3ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'b00c28b3-319c-44f5-906d-c24b3debafd7\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:29.418Z',\n          '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/b00c28b3-319c-44f5-906d-c24b3debafd7/click  ',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:19:29.631Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/b00c28b3-319c-44f5-906d-c24b3debafd7/click (213ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:29.634Z',\n          '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/execute/sync  ',\n          '{\\n     script: \\'var passedArgs = Array.prototype.slice.call(arguments,0); return (function(listName) {\\\\n\\' +\\n       \\'      // executed in the browser context\\\\n\\' +\\n       \\'      // eslint-disable-next-line\\\\n\\' +\\n       \\'      var elements = document.querySel... (366 characters)\\',\\n     args: [ \\'todoList.todos\\' ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:29.637Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/execute/sync (3ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'df85178f-1166-489c-827d-17e13fecf95a\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ed6dc16b-f99b-4ab7-821b-c17030dcd5de\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f201c631-099d-4556-b725-1b9036ff21e7\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:29.643Z',\n          '  Request GET /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/text  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:29.656Z',\n          '  Response 200 GET /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/text (13ms)',\n          '{ value: \\'what is nightwatch?\\' }'\n        ],\n        [\n          '2023-04-06T10:19:29.659Z',\n          '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/element  ',\n          '{ using: \\'css selector\\', value: \\'input\\' }'\n        ],\n        [\n          '2023-04-06T10:19:29.662Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/element (3ms)',\n          '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'8b05c802-195a-4804-a216-09892ca94a68\\'\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:29.663Z',\n          '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/8b05c802-195a-4804-a216-09892ca94a68/click  ',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:19:29.875Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/8b05c802-195a-4804-a216-09892ca94a68/click (212ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:29.879Z',\n          '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  ',\n          '{ using: \\'css selector\\', value: \\'*[module=todoApp] li .done-true\\' }'\n        ],\n        [\n          '2023-04-06T10:19:29.883Z',\n          '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (4ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f027fd19-1bf0-406e-899c-c005c1e40456\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ed3f1754-6119-41a2-83c1-d56075d6b38a\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:29.893Z',\n          '  Request DELETE /session/1a5fbc5c-7381-4c6e-991b-936453257b8d  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:30.257Z',\n          '  Response 200 DELETE /session/1a5fbc5c-7381-4c6e-991b-936453257b8d (365ms)',\n          '{ value: null }'\n        ]\n      ]\n    },\n    duckDuckGo: {\n      reportPrefix: 'FIREFOX_111.0.1__',\n      assertionsCount: 1,\n      lastError: {\n        name: 'NightwatchAssertError',\n        message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n        showDiff: false,\n        abortOnFailure: true,\n        waitFor: true,\n        stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)'\n      },\n      skippedAtRuntime: [\n      ],\n      skipped: [\n      ],\n      time: '5.777',\n      timeMs: 5777,\n      completed: {\n        'Search Nightwatch.js and check results': {\n          time: '5.777',\n          assertions: [\n            {\n              name: 'NightwatchAssertError',\n              message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \"visible\" but got: \"not found\" (5088ms)',\n              stackTrace: '    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n              fullMsg: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n              failure: 'Expected \"visible\" but got: \"not found\"',\n              screenshots: [\n                '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154934-GMT+0530.png'\n              ]\n            }\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 1,\n          skipped: 0,\n          tests: 1,\n          status: 'fail',\n          steps: [\n          ],\n          stackTrace: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n          testcases: {\n            'Search Nightwatch.js and check results': {\n              time: '5.777',\n              assertions: [\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n                  stackTrace: '    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n                  fullMsg: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n                  failure: 'Expected \"visible\" but got: \"not found\"',\n                  screenshots: [\n                    '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154934-GMT+0530.png'\n                  ]\n                }\n              ],\n              tests: 1,\n              commands: [\n              ],\n              passed: 0,\n              errors: 0,\n              failed: 1,\n              skipped: 0,\n              status: 'fail',\n              steps: [\n              ],\n              stackTrace: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n              lastError: {\n                name: 'NightwatchAssertError',\n                message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n                showDiff: false,\n                abortOnFailure: true,\n                waitFor: true,\n                stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)'\n              },\n              timeMs: 5777,\n              startTimestamp: 'Thu, 06 Apr 2023 10:19:29 GMT',\n              endTimestamp: 'Thu, 06 Apr 2023 10:19:34 GMT'\n            }\n          },\n          lastError: {\n            name: 'NightwatchAssertError',\n            message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n            showDiff: false,\n            abortOnFailure: true,\n            waitFor: true,\n            stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)'\n          },\n          timeMs: 5777,\n          startTimestamp: 'Thu, 06 Apr 2023 10:19:29 GMT',\n          endTimestamp: 'Thu, 06 Apr 2023 10:19:34 GMT'\n        }\n      },\n      completedSections: {\n        __global_beforeEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __before_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        'Search Nightwatch.js and check results': {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'navigateTo',\n              args: [\n                'https://duckduckgo.com'\n              ],\n              startTime: 1680776369008,\n              endTime: 1680776369560,\n              elapsedTime: 552,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'waitForElementVisible',\n              args: [\n                '#search_form_input_homepage'\n              ],\n              startTime: 1680776369561,\n              endTime: 1680776374652,\n              elapsedTime: 5091,\n              status: 'fail',\n              result: {\n                message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \"visible\" but got: \"not found\" (5088ms)',\n                showDiff: false,\n                name: 'NightwatchAssertError',\n                abortOnFailure: true,\n                stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n                beautifiedStack: {\n                  filePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js',\n                  error_line_number: 8,\n                  codeSnippet: [\n                    {\n                      line_number: 6,\n                      code: '    browser'\n                    },\n                    {\n                      line_number: 7,\n                      code: '      .navigateTo(\\'https://duckduckgo.com\\')'\n                    },\n                    {\n                      line_number: 8,\n                      code: '      .waitForElementVisible(\\'#search_form_input_homepage\\')'\n                    },\n                    {\n                      line_number: 9,\n                      code: '      .sendKeys(\\'#search_form_input_homepage\\', [\\'Nightwatch.js\\'])'\n                    },\n                    {\n                      line_number: 10,\n                      code: '      .click(\\'#search_button_homepage\\')'\n                    }\n                  ]\n                }\n              },\n              screenshot: '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154934-GMT+0530.png'\n            },\n            {\n              name: 'saveScreenshot',\n              args: [\n                '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154934-GMT+0530.png',\n                'function () { [native code] }'\n              ],\n              startTime: 1680776374705,\n              endTime: 1680776374779,\n              elapsedTime: 74,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'fail'\n        },\n        __after_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __global_afterEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'end',\n              args: [\n                'true'\n              ],\n              startTime: 1680776374783,\n              endTime: 1680776375248,\n              elapsedTime: 465,\n              status: 'pass'\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        }\n      },\n      errmessages: [\n      ],\n      testsCount: 1,\n      skippedCount: 0,\n      failedCount: 1,\n      errorsCount: 0,\n      passedCount: 0,\n      group: '',\n      modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js',\n      startTimestamp: 'Thu, 06 Apr 2023 10:19:26 GMT',\n      endTimestamp: 'Thu, 06 Apr 2023 10:19:34 GMT',\n      sessionCapabilities: {\n        acceptInsecureCerts: false,\n        browserName: 'firefox',\n        browserVersion: '111.0.1',\n        'moz:accessibilityChecks': false,\n        'moz:buildID': '20230321111920',\n        'moz:geckodriverVersion': '0.32.0',\n        'moz:headless': false,\n        'moz:platformVersion': '22.3.0',\n        'moz:processID': 93718,\n        'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile7QoCZB',\n        'moz:shutdownTimeout': 60000,\n        'moz:useNonSpecCompliantPointerOrigin': false,\n        'moz:webdriverClick': true,\n        'moz:windowless': false,\n        pageLoadStrategy: 'normal',\n        platformName: 'mac',\n        proxy: {\n        },\n        setWindowRect: true,\n        strictFileInteractability: false,\n        timeouts: {\n          implicit: 0,\n          pageLoad: 300000,\n          script: 30000\n        },\n        unhandledPromptBehavior: 'dismiss and notify'\n      },\n      sessionId: '57729330-9108-4abf-9b31-a590c5cdf0e9',\n      projectName: '',\n      buildName: '',\n      testEnv: 'firefox',\n      isMobile: false,\n      status: 'fail',\n      seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/duckDuckGo_geckodriver.log',\n      host: 'localhost',\n      tests: 1,\n      failures: 1,\n      errors: 0,\n      httpOutput: [\n        [\n          '2023-04-06T10:19:27.321Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:28.997Z',\n          '  Response 200 POST /session (1678ms)',\n          '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;57729330-9108-4abf-9b31-a590c5cdf0e9&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93718<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile7QoCZB&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.011Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/url  </span></b>',\n          '{ url: <span style=\"color:#0A0\">&#39;https://duckduckgo.com&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.559Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/url (549ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:29.563Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:29.573Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (10ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:30.075Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:30.077Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (2ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:30.581Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:30.599Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (18ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:31.101Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:31.106Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (5ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:31.608Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:31.611Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:32.115Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:32.120Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (6ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:32.622Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:32.625Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:33.128Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:33.132Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (4ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:33.635Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:33.638Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:34.140Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:34.144Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (4ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:34.646Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:34.649Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:34.708Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/57729330-9108-4abf-9b31-a590c5cdf0e9/screenshot  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:34.774Z',\n          '  Response 200 GET /session/57729330-9108-4abf-9b31-a590c5cdf0e9/screenshot (54ms)',\n          '{\\n     value: <span style=\"color:#0A0\">&#39;iVBORw0KGgoAAAANSUhEUgAACgAAAAV8CAYAAAD3/MaLAAAgAElEQVR4XuzdeZhcZZk34Kf39JLuzr5CCIQlIARZBJTFBRVRRNEZ...&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:34.787Z',\n          '  Request <b><span style=\"color:#0AA\">DELETE /session/57729330-9108-4abf-9b31-a590c5cdf0e9  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:35.245Z',\n          '  Response 200 DELETE /session/57729330-9108-4abf-9b31-a590c5cdf0e9 (456ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ]\n      ],\n      rawHttpOutput: [\n        [\n          '2023-04-06T10:19:27.321Z',\n          '  Request POST /session  ',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:28.997Z',\n          '  Response 200 POST /session (1678ms)',\n          '{\\n     value: {\\n       sessionId: \\'57729330-9108-4abf-9b31-a590c5cdf0e9\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93718,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile7QoCZB\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:29.011Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/url  ',\n          '{ url: \\'https://duckduckgo.com\\' }'\n        ],\n        [\n          '2023-04-06T10:19:29.559Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/url (549ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:29.563Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:29.573Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (10ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:30.075Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:30.077Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (2ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:30.581Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:30.599Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (18ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:31.101Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:31.106Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (5ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:31.608Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:31.611Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:32.115Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:32.120Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (6ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:32.622Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:32.625Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:33.128Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:33.132Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (4ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:33.635Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:33.638Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:34.140Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:34.144Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (4ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:34.646Z',\n          '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n          '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n        ],\n        [\n          '2023-04-06T10:19:34.649Z',\n          '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:34.708Z',\n          '  Request GET /session/57729330-9108-4abf-9b31-a590c5cdf0e9/screenshot  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:34.774Z',\n          '  Response 200 GET /session/57729330-9108-4abf-9b31-a590c5cdf0e9/screenshot (54ms)',\n          '{\\n     value: \\'iVBORw0KGgoAAAANSUhEUgAACgAAAAV8CAYAAAD3/MaLAAAgAElEQVR4XuzdeZhcZZk34Kf39JLuzr5CCIQlIARZBJTFBRVRRNEZ...\\',\\n     suppressBase64Data: true\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:34.787Z',\n          '  Request DELETE /session/57729330-9108-4abf-9b31-a590c5cdf0e9  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:35.245Z',\n          '  Response 200 DELETE /session/57729330-9108-4abf-9b31-a590c5cdf0e9 (456ms)',\n          '{ value: null }'\n        ]\n      ],\n      globalErrorRegister: [\n        '   \\u001b[1;31m→ ✖ \\u001b[1;31mNightwatchAssertError\\u001b[0m\\n   \\u001b[0;31mTimed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m\\u001b[0m\\n\\u001b[0;33m\\n    Error location:\\u001b[0m\\n    /Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:\\n    –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––\\n     6 |     browser\\n     7 |       .navigateTo(\\'https://duckduckgo.com\\')\\n    \\u001b[0;37m\\u001b[41m 8 |       .waitForElementVisible(\\'#search_form_input_homepage\\') \\u001b[0m\\n     9 |       .sendKeys(\\'#search_form_input_homepage\\', [\\'Nightwatch.js\\'])\\n     10 |       .click(\\'#search_button_homepage\\')\\n    –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––\\n\\u001b[0m'\n      ]\n    },\n    googlePageObject: {\n      reportPrefix: '',\n      assertionsCount: 0,\n      lastError: null,\n      skippedAtRuntime: [\n        'should complete the consent form'\n      ],\n      skipped: [\n        'should complete the consent form'\n      ],\n      time: 0,\n      completed: {\n      },\n      completedSections: {\n      },\n      errmessages: [\n      ],\n      testsCount: 0,\n      skippedCount: 1,\n      failedCount: 0,\n      errorsCount: 0,\n      passedCount: 0,\n      group: '',\n      modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/googlePageObject.js',\n      startTimestamp: 'Thu, 06 Apr 2023 10:19:36 GMT',\n      endTimestamp: 'Thu, 06 Apr 2023 10:19:36 GMT',\n      sessionCapabilities: {\n        browserName: 'firefox',\n        alwaysMatch: {\n          acceptInsecureCerts: true,\n          'moz:firefoxOptions': {\n            args: [\n            ]\n          }\n        },\n        name: 'google search with consent form - page objects'\n      },\n      sessionId: '',\n      projectName: '',\n      buildName: '',\n      testEnv: 'firefox',\n      isMobile: false,\n      status: 'skip',\n      host: 'localhost',\n      tests: 0,\n      failures: 0,\n      errors: 0,\n      httpOutput: [\n      ],\n      rawHttpOutput: [\n      ]\n    },\n    google: {\n      reportPrefix: 'FIREFOX_111.0.1__',\n      assertionsCount: 2,\n      lastError: null,\n      skippedAtRuntime: [\n      ],\n      skipped: [\n      ],\n      time: '10.68',\n      timeMs: 10675,\n      completed: {\n        'demo test using expect apis': {\n          time: '10.68',\n          assertions: [\n            {\n              name: 'NightwatchAssertError',\n              message: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n              stackTrace: '',\n              fullMsg: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Testing if element <#rso>:first-child> contains text \\'Nightwatch.js\\' (1069ms)',\n              stackTrace: '',\n              fullMsg: 'Testing if element \\u001b[0;33m<#rso>:first-child>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(1069ms)\\u001b[0m',\n              failure: false\n            }\n          ],\n          commands: [\n          ],\n          passed: 2,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 2,\n          status: 'pass',\n          steps: [\n          ],\n          stackTrace: '',\n          testcases: {\n            'demo test using expect apis': {\n              time: '10.68',\n              assertions: [\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n                  stackTrace: '',\n                  fullMsg: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Testing if element \\u001b[0;33m<#rso>:first-child>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(1069ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Testing if element \\u001b[0;33m<#rso>:first-child>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(1069ms)\\u001b[0m',\n                  failure: false\n                }\n              ],\n              tests: 2,\n              commands: [\n              ],\n              passed: 2,\n              errors: 0,\n              failed: 0,\n              skipped: 0,\n              status: 'pass',\n              steps: [\n              ],\n              stackTrace: '',\n              timeMs: 10675,\n              startTimestamp: 'Thu, 06 Apr 2023 10:19:35 GMT',\n              endTimestamp: 'Thu, 06 Apr 2023 10:19:46 GMT'\n            }\n          },\n          timeMs: 10675,\n          startTimestamp: 'Thu, 06 Apr 2023 10:19:35 GMT',\n          endTimestamp: 'Thu, 06 Apr 2023 10:19:46 GMT'\n        }\n      },\n      completedSections: {\n        __global_beforeEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __before_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        'demo test using expect apis': {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'navigateTo',\n              args: [\n                'http://google.no'\n              ],\n              startTime: 1680776375516,\n              endTime: 1680776379577,\n              elapsedTime: 4061,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'isPresent',\n              args: [\n                '[aria-modal=\"true\"][title=\"Before you continue to Google Search\"]'\n              ],\n              startTime: 1680776379578,\n              endTime: 1680776384672,\n              elapsedTime: 5094,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'waitForElementVisible',\n              args: [\n                'form[action=\"/search\"] input[type=text]'\n              ],\n              startTime: 1680776384675,\n              endTime: 1680776384690,\n              elapsedTime: 15,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'sendKeys',\n              args: [\n                'form[action=\"/search\"] input[type=text]',\n                'Nightwatch.js,'\n              ],\n              startTime: 1680776384690,\n              endTime: 1680776384728,\n              elapsedTime: 38,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'assert.textContains',\n              args: [\n                '#rso>:first-child',\n                'Nightwatch.js'\n              ],\n              startTime: 1680776384728,\n              endTime: 1680776385800,\n              elapsedTime: 1072,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'end',\n              args: [\n              ],\n              startTime: 1680776385800,\n              endTime: 1680776386186,\n              elapsedTime: 386,\n              status: 'pass'\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __after_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __global_afterEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        }\n      },\n      errmessages: [\n      ],\n      testsCount: 1,\n      skippedCount: 0,\n      failedCount: 0,\n      errorsCount: 0,\n      passedCount: 2,\n      group: '',\n      modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/google.js',\n      startTimestamp: 'Thu, 06 Apr 2023 10:19:33 GMT',\n      endTimestamp: 'Thu, 06 Apr 2023 10:19:46 GMT',\n      sessionCapabilities: {\n        acceptInsecureCerts: false,\n        browserName: 'firefox',\n        browserVersion: '111.0.1',\n        'moz:accessibilityChecks': false,\n        'moz:buildID': '20230321111920',\n        'moz:geckodriverVersion': '0.32.0',\n        'moz:headless': false,\n        'moz:platformVersion': '22.3.0',\n        'moz:processID': 93775,\n        'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileoRDuKX',\n        'moz:shutdownTimeout': 60000,\n        'moz:useNonSpecCompliantPointerOrigin': false,\n        'moz:webdriverClick': true,\n        'moz:windowless': false,\n        pageLoadStrategy: 'normal',\n        platformName: 'mac',\n        proxy: {\n        },\n        setWindowRect: true,\n        strictFileInteractability: false,\n        timeouts: {\n          implicit: 0,\n          pageLoad: 300000,\n          script: 30000\n        },\n        unhandledPromptBehavior: 'dismiss and notify'\n      },\n      sessionId: 'c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d',\n      projectName: '',\n      buildName: '',\n      testEnv: 'firefox',\n      isMobile: false,\n      status: 'pass',\n      host: 'localhost',\n      tests: 1,\n      failures: 0,\n      errors: 0,\n      httpOutput: [\n        [\n          '2023-04-06T10:19:34.090Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:35.510Z',\n          '  Response 200 POST /session (1421ms)',\n          '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93775<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileoRDuKX&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:35.517Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/url  </span></b>',\n          '{ url: <span style=\"color:#0A0\">&#39;http://google.no&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:39.576Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/url (4059ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:39.580Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:39.588Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:40.091Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:40.096Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (6ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:40.598Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:40.600Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:41.103Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:41.111Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:41.614Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:41.620Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (7ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:42.123Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.128Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (6ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:42.630Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:42.637Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:43.140Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:43.154Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (15ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:43.656Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:43.659Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:44.161Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.163Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (2ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:44.665Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.669Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:44.676Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;form[action=&quot;/search&quot;] input[type=text]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.680Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;d11d4330-8ae2-44c8-b64a-3971618fbde5&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.682Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;d11d4330-8ae2-44c8-b64a-3971618fbde5&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;d11d4330-8ae2-44c8-b64a-3971618fbde5&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.689Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/execute/sync (7ms)',\n          '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.691Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;form[action=&quot;/search&quot;] input[type=text]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.694Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;d11d4330-8ae2-44c8-b64a-3971618fbde5&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.695Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/d11d4330-8ae2-44c8-b64a-3971618fbde5/value  </span></b>',\n          '{\\n     text: <span style=\"color:#0A0\">&#39;Nightwatch.js&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;N&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;.&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;j&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.727Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/d11d4330-8ae2-44c8-b64a-3971618fbde5/value (32ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:44.730Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#rso&gt;:first-child&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:44.732Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (2ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:45.235Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#rso&gt;:first-child&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:45.238Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:45.741Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#rso&gt;:first-child&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:45.744Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;1e7d46f7-02cf-45c5-9db9-6673572e7e78&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:45.746Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/1e7d46f7-02cf-45c5-9db9-6673572e7e78/text  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:45.797Z',\n          '  Response 200 GET /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/1e7d46f7-02cf-45c5-9db9-6673572e7e78/text (51ms)',\n          '{\\n     value: <span style=\"color:#0A0\">&#39;Web result with site links\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwatch.js | Node.js powered End-to-End testing framework\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwatch....&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:45.803Z',\n          '  Request <b><span style=\"color:#0AA\">DELETE /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:46.185Z',\n          '  Response 200 DELETE /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d (383ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ]\n      ],\n      rawHttpOutput: [\n        [\n          '2023-04-06T10:19:34.090Z',\n          '  Request POST /session  ',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:35.510Z',\n          '  Response 200 POST /session (1421ms)',\n          '{\\n     value: {\\n       sessionId: \\'c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93775,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileoRDuKX\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:35.517Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/url  ',\n          '{ url: \\'http://google.no\\' }'\n        ],\n        [\n          '2023-04-06T10:19:39.576Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/url (4059ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:39.580Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:39.588Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:40.091Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:40.096Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (6ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:40.598Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:40.600Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:41.103Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:41.111Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:41.614Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:41.620Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (7ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:42.123Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:42.128Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (6ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:42.630Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:42.637Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:43.140Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:43.154Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (15ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:43.656Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:43.659Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:44.161Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:44.163Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (2ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:44.665Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:44.669Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:44.676Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'form[action=&quot;/search&quot;] input[type=text]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:44.680Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'d11d4330-8ae2-44c8-b64a-3971618fbde5\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:44.682Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'d11d4330-8ae2-44c8-b64a-3971618fbde5\\',\\n         ELEMENT: \\'d11d4330-8ae2-44c8-b64a-3971618fbde5\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:44.689Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/execute/sync (7ms)',\n          '{ value: true }'\n        ],\n        [\n          '2023-04-06T10:19:44.691Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{\\n     using: \\'css selector\\',\\n     value: \\'form[action=&quot;/search&quot;] input[type=text]\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:44.694Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'d11d4330-8ae2-44c8-b64a-3971618fbde5\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:44.695Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/d11d4330-8ae2-44c8-b64a-3971618fbde5/value  ',\n          '{\\n     text: \\'Nightwatch.js\\',\\n     value: [\\n       \\'N\\', \\'i\\', \\'g\\', \\'h\\',\\n       \\'t\\', \\'w\\', \\'a\\', \\'t\\',\\n       \\'c\\', \\'h\\', \\'.\\', \\'j\\',\\n       \\'s\\', \\'\\'\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:44.727Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/d11d4330-8ae2-44c8-b64a-3971618fbde5/value (32ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:44.730Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{ using: \\'css selector\\', value: \\'#rso&gt;:first-child\\' }'\n        ],\n        [\n          '2023-04-06T10:19:44.732Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (2ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:45.235Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{ using: \\'css selector\\', value: \\'#rso&gt;:first-child\\' }'\n        ],\n        [\n          '2023-04-06T10:19:45.238Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n          '{ value: [] }'\n        ],\n        [\n          '2023-04-06T10:19:45.741Z',\n          '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n          '{ using: \\'css selector\\', value: \\'#rso&gt;:first-child\\' }'\n        ],\n        [\n          '2023-04-06T10:19:45.744Z',\n          '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'1e7d46f7-02cf-45c5-9db9-6673572e7e78\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:45.746Z',\n          '  Request GET /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/1e7d46f7-02cf-45c5-9db9-6673572e7e78/text  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:45.797Z',\n          '  Response 200 GET /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/1e7d46f7-02cf-45c5-9db9-6673572e7e78/text (51ms)',\n          '{\\n     value: \\'Web result with site links\\\\n\\' +\\n       \\'\\\\n\\' +\\n       \\'Nightwatch.js | Node.js powered End-to-End testing framework\\\\n\\' +\\n       \\'Nightwatch....\\',\\n     suppressBase64Data: true\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:45.803Z',\n          '  Request DELETE /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:46.185Z',\n          '  Response 200 DELETE /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d (383ms)',\n          '{ value: null }'\n        ]\n      ]\n    },\n    shadowRootExample: {\n      reportPrefix: '',\n      assertionsCount: 0,\n      lastError: null,\n      skippedAtRuntime: [\n        'retrieve the shadowRoot'\n      ],\n      skipped: [\n        'retrieve the shadowRoot'\n      ],\n      time: 0,\n      completed: {\n      },\n      completedSections: {\n      },\n      errmessages: [\n      ],\n      testsCount: 0,\n      skippedCount: 1,\n      failedCount: 0,\n      errorsCount: 0,\n      passedCount: 0,\n      group: '',\n      modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/shadowRootExample.js',\n      startTimestamp: 'Thu, 06 Apr 2023 10:19:45 GMT',\n      endTimestamp: 'Thu, 06 Apr 2023 10:19:45 GMT',\n      sessionCapabilities: {\n        browserName: 'firefox',\n        alwaysMatch: {\n          acceptInsecureCerts: true,\n          'moz:firefoxOptions': {\n            args: [\n            ]\n          }\n        },\n        name: 'Shadow Root example test'\n      },\n      sessionId: '',\n      projectName: '',\n      buildName: '',\n      testEnv: 'firefox',\n      isMobile: false,\n      status: 'skip',\n      host: 'localhost',\n      tests: 0,\n      failures: 0,\n      errors: 0,\n      httpOutput: [\n      ],\n      rawHttpOutput: [\n      ]\n    },\n    vueTodoList: {\n      reportPrefix: 'FIREFOX_111.0.1__',\n      assertionsCount: 3,\n      lastError: null,\n      skippedAtRuntime: [\n      ],\n      skipped: [\n      ],\n      time: '1.251',\n      timeMs: 1251,\n      completed: {\n        'should add a todo using global element()': {\n          time: '1.251',\n          assertions: [\n            {\n              name: 'NightwatchAssertError',\n              message: 'Expected elements <#todo-list ul li> count to equal: \"5\" (4ms)',\n              stackTrace: '',\n              fullMsg: 'Expected elements <#todo-list ul li> count to equal: \\u001b[0;33m\"5\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Expected element <#todo-list ul li> text to contain: \"what is nightwatch?\" (15ms)',\n              stackTrace: '',\n              fullMsg: 'Expected element <#todo-list ul li> text to contain: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Expected elements <#todo-list ul li input:checked> count to equal: \"3\" (4ms)',\n              stackTrace: '',\n              fullMsg: 'Expected elements <#todo-list ul li input:checked> count to equal: \\u001b[0;33m\"3\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n              failure: false\n            }\n          ],\n          commands: [\n          ],\n          passed: 3,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 3,\n          status: 'pass',\n          steps: [\n          ],\n          stackTrace: '',\n          testcases: {\n            'should add a todo using global element()': {\n              time: '1.251',\n              assertions: [\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Expected elements <#todo-list ul li> count to equal: \\u001b[0;33m\"5\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Expected elements <#todo-list ul li> count to equal: \\u001b[0;33m\"5\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Expected element <#todo-list ul li> text to contain: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Expected element <#todo-list ul li> text to contain: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Expected elements <#todo-list ul li input:checked> count to equal: \\u001b[0;33m\"3\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Expected elements <#todo-list ul li input:checked> count to equal: \\u001b[0;33m\"3\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n                  failure: false\n                }\n              ],\n              tests: 3,\n              commands: [\n              ],\n              passed: 3,\n              errors: 0,\n              failed: 0,\n              skipped: 0,\n              status: 'pass',\n              steps: [\n              ],\n              stackTrace: '',\n              timeMs: 1251,\n              startTimestamp: 'Thu, 06 Apr 2023 10:19:47 GMT',\n              endTimestamp: 'Thu, 06 Apr 2023 10:19:48 GMT'\n            }\n          },\n          timeMs: 1251,\n          startTimestamp: 'Thu, 06 Apr 2023 10:19:47 GMT',\n          endTimestamp: 'Thu, 06 Apr 2023 10:19:48 GMT'\n        }\n      },\n      completedSections: {\n        __global_beforeEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __before_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        'should add a todo using global element()': {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'navigateTo',\n              args: [\n                'https://todo-vue3-vite.netlify.app/'\n              ],\n              startTime: 1680776387084,\n              endTime: 1680776387841,\n              elapsedTime: 757,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'sendKeys',\n              args: [\n                '#new-todo-input',\n                'what is nightwatch?'\n              ],\n              startTime: 1680776387841,\n              endTime: 1680776387864,\n              elapsedTime: 23,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'click',\n              args: [\n                'form button[type=\"submit\"]'\n              ],\n              startTime: 1680776387865,\n              endTime: 1680776388087,\n              elapsedTime: 222,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'expect.elements',\n              args: [\n                '#todo-list ul li'\n              ],\n              startTime: 1680776388091,\n              endTime: 1680776388095,\n              elapsedTime: 4,\n              status: 'pass',\n              result: {\n              }\n            },\n            {\n              name: 'expect.element',\n              args: [\n                '#todo-list ul li'\n              ],\n              startTime: 1680776388096,\n              endTime: 1680776388111,\n              elapsedTime: 15,\n              status: 'pass',\n              result: {\n              }\n            },\n            {\n              name: 'element().findElement',\n              args: [\n                '[object Object]'\n              ],\n              startTime: 1680776388111,\n              endTime: 1680776388114,\n              elapsedTime: 3,\n              status: 'pass',\n              result: {\n              }\n            },\n            {\n              name: 'click',\n              args: [\n                '[object Object]'\n              ],\n              startTime: 1680776388116,\n              endTime: 1680776388327,\n              elapsedTime: 211,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'expect.elements',\n              args: [\n                '#todo-list ul li input:checked'\n              ],\n              startTime: 1680776388328,\n              endTime: 1680776388332,\n              elapsedTime: 4,\n              status: 'pass',\n              result: {\n              }\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __after_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __global_afterEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'end',\n              args: [\n                'true'\n              ],\n              startTime: 1680776388337,\n              endTime: 1680776389341,\n              elapsedTime: 1004,\n              status: 'pass'\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        }\n      },\n      errmessages: [\n      ],\n      testsCount: 1,\n      skippedCount: 0,\n      failedCount: 0,\n      errorsCount: 0,\n      passedCount: 3,\n      group: '',\n      modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/vueTodoList.js',\n      startTimestamp: 'Thu, 06 Apr 2023 10:19:45 GMT',\n      endTimestamp: 'Thu, 06 Apr 2023 10:19:48 GMT',\n      sessionCapabilities: {\n        acceptInsecureCerts: false,\n        browserName: 'firefox',\n        browserVersion: '111.0.1',\n        'moz:accessibilityChecks': false,\n        'moz:buildID': '20230321111920',\n        'moz:geckodriverVersion': '0.32.0',\n        'moz:headless': false,\n        'moz:platformVersion': '22.3.0',\n        'moz:processID': 93855,\n        'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile2iTSVu',\n        'moz:shutdownTimeout': 60000,\n        'moz:useNonSpecCompliantPointerOrigin': false,\n        'moz:webdriverClick': true,\n        'moz:windowless': false,\n        pageLoadStrategy: 'normal',\n        platformName: 'mac',\n        proxy: {\n        },\n        setWindowRect: true,\n        strictFileInteractability: false,\n        timeouts: {\n          implicit: 0,\n          pageLoad: 300000,\n          script: 30000\n        },\n        unhandledPromptBehavior: 'dismiss and notify'\n      },\n      sessionId: '02cdc21b-3ae3-4f80-b595-07f8498c4a11',\n      projectName: '',\n      buildName: '',\n      testEnv: 'firefox',\n      isMobile: false,\n      status: 'pass',\n      seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/vueTodoList_geckodriver.log',\n      host: 'localhost',\n      tests: 1,\n      failures: 0,\n      errors: 0,\n      httpOutput: [\n        [\n          '2023-04-06T10:19:45.864Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:47.078Z',\n          '  Response 200 POST /session (1217ms)',\n          '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;02cdc21b-3ae3-4f80-b595-07f8498c4a11&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93855<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile2iTSVu&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:47.085Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/url  </span></b>',\n          '{ url: <span style=\"color:#0A0\">&#39;https://todo-vue3-vite.netlify.app/&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:19:47.840Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/url (755ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:47.843Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#new-todo-input&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:47.848Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (6ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;cbf47355-2c00-4daf-b3b5-8179d43d1e88&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:47.851Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/cbf47355-2c00-4daf-b3b5-8179d43d1e88/value  </span></b>',\n          '{\\n     text: <span style=\"color:#0A0\">&#39;what is nightwatch?&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;n&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;?&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:47.863Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/cbf47355-2c00-4daf-b3b5-8179d43d1e88/value (13ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:47.867Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;form button[type=&quot;submit&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:47.871Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (5ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:47.873Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed/click  </span></b>',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:19:48.087Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed/click (215ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:48.092Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#todo-list ul li&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:48.094Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9fba7102-78a1-4f16-8085-471f605574cf&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;d8c3dbca-d8d8-4395-bdee-5dd16a889d37&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;320b0952-82ca-4c8d-b91b-36141f695c14&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f8514d2e-85c6-4991-8920-31e10a6d7f88&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;2bfecd6d-d71c-4946-97bd-5521f6a31055&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:48.096Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#todo-list ul li&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:48.098Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9fba7102-78a1-4f16-8085-471f605574cf&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;d8c3dbca-d8d8-4395-bdee-5dd16a889d37&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;320b0952-82ca-4c8d-b91b-36141f695c14&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f8514d2e-85c6-4991-8920-31e10a6d7f88&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;2bfecd6d-d71c-4946-97bd-5521f6a31055&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:48.099Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/text  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:48.110Z',\n          '  Response 200 GET /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/text (11ms)',\n          '{\\n     value: <span style=\"color:#0A0\">&#39;new taskwhat is nightwatch?\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Edit\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;New Taskwhat Is Nightwatch?\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Delete\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;New Taskwhat Is Nightwatch?&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:48.112Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/element  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=&quot;checkbox&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:48.114Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/element (2ms)',\n          '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9db02cb5-bb43-4ef1-b935-38a417240ee2&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:48.117Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/9db02cb5-bb43-4ef1-b935-38a417240ee2/click  </span></b>',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:19:48.327Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/9db02cb5-bb43-4ef1-b935-38a417240ee2/click (209ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:19:48.329Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#todo-list ul li input:checked&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:48.331Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;a6373a47-f735-4162-bb2d-36b5aa4756a4&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;56a696cc-b2f5-4300-8428-0bcf93409417&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9db02cb5-bb43-4ef1-b935-38a417240ee2&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:48.340Z',\n          '  Request <b><span style=\"color:#0AA\">DELETE /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:19:49.340Z',\n          '  Response 200 DELETE /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11 (1000ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ]\n      ],\n      rawHttpOutput: [\n        [\n          '2023-04-06T10:19:45.864Z',\n          '  Request POST /session  ',\n          '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:47.078Z',\n          '  Response 200 POST /session (1217ms)',\n          '{\\n     value: {\\n       sessionId: \\'02cdc21b-3ae3-4f80-b595-07f8498c4a11\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93855,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile2iTSVu\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:47.085Z',\n          '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/url  ',\n          '{ url: \\'https://todo-vue3-vite.netlify.app/\\' }'\n        ],\n        [\n          '2023-04-06T10:19:47.840Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/url (755ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:47.843Z',\n          '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  ',\n          '{ using: \\'css selector\\', value: \\'#new-todo-input\\' }'\n        ],\n        [\n          '2023-04-06T10:19:47.848Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (6ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'cbf47355-2c00-4daf-b3b5-8179d43d1e88\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:47.851Z',\n          '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/cbf47355-2c00-4daf-b3b5-8179d43d1e88/value  ',\n          '{\\n     text: \\'what is nightwatch?\\',\\n     value: [\\n       \\'w\\', \\'h\\', \\'a\\', \\'t\\', \\' \\',\\n       \\'i\\', \\'s\\', \\' \\', \\'n\\', \\'i\\',\\n       \\'g\\', \\'h\\', \\'t\\', \\'w\\', \\'a\\',\\n       \\'t\\', \\'c\\', \\'h\\', \\'?\\'\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:47.863Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/cbf47355-2c00-4daf-b3b5-8179d43d1e88/value (13ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:47.867Z',\n          '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  ',\n          '{ using: \\'css selector\\', value: \\'form button[type=&quot;submit&quot;]\\' }'\n        ],\n        [\n          '2023-04-06T10:19:47.871Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (5ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:47.873Z',\n          '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed/click  ',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:19:48.087Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed/click (215ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:48.092Z',\n          '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  ',\n          '{ using: \\'css selector\\', value: \\'#todo-list ul li\\' }'\n        ],\n        [\n          '2023-04-06T10:19:48.094Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9fba7102-78a1-4f16-8085-471f605574cf\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'d8c3dbca-d8d8-4395-bdee-5dd16a889d37\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'320b0952-82ca-4c8d-b91b-36141f695c14\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f8514d2e-85c6-4991-8920-31e10a6d7f88\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'2bfecd6d-d71c-4946-97bd-5521f6a31055\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:48.096Z',\n          '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  ',\n          '{ using: \\'css selector\\', value: \\'#todo-list ul li\\' }'\n        ],\n        [\n          '2023-04-06T10:19:48.098Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9fba7102-78a1-4f16-8085-471f605574cf\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'d8c3dbca-d8d8-4395-bdee-5dd16a889d37\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'320b0952-82ca-4c8d-b91b-36141f695c14\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f8514d2e-85c6-4991-8920-31e10a6d7f88\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'2bfecd6d-d71c-4946-97bd-5521f6a31055\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:48.099Z',\n          '  Request GET /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/text  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:48.110Z',\n          '  Response 200 GET /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/text (11ms)',\n          '{\\n     value: \\'new taskwhat is nightwatch?\\\\n\\' +\\n       \\'Edit\\\\n\\' +\\n       \\'New Taskwhat Is Nightwatch?\\\\n\\' +\\n       \\'Delete\\\\n\\' +\\n       \\'New Taskwhat Is Nightwatch?\\'\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:48.112Z',\n          '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/element  ',\n          '{ using: \\'css selector\\', value: \\'input[type=&quot;checkbox&quot;]\\' }'\n        ],\n        [\n          '2023-04-06T10:19:48.114Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/element (2ms)',\n          '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9db02cb5-bb43-4ef1-b935-38a417240ee2\\'\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:48.117Z',\n          '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/9db02cb5-bb43-4ef1-b935-38a417240ee2/click  ',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:19:48.327Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/9db02cb5-bb43-4ef1-b935-38a417240ee2/click (209ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:19:48.329Z',\n          '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  ',\n          '{ using: \\'css selector\\', value: \\'#todo-list ul li input:checked\\' }'\n        ],\n        [\n          '2023-04-06T10:19:48.331Z',\n          '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'a6373a47-f735-4162-bb2d-36b5aa4756a4\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'56a696cc-b2f5-4300-8428-0bcf93409417\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9db02cb5-bb43-4ef1-b935-38a417240ee2\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:19:48.340Z',\n          '  Request DELETE /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:19:49.340Z',\n          '  Response 200 DELETE /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11 (1000ms)',\n          '{ value: null }'\n        ]\n      ]\n    },\n    ecosia: {\n      reportPrefix: 'CHROME_111.0.5563.146__',\n      assertionsCount: 5,\n      lastError: null,\n      skippedAtRuntime: [\n      ],\n      skipped: [\n      ],\n      time: '3.056',\n      timeMs: 3056,\n      completed: {\n        'Demo test ecosia.org': {\n          time: '3.056',\n          assertions: [\n            {\n              name: 'NightwatchAssertError',\n              message: 'Element <body> was visible after 39 milliseconds.',\n              stackTrace: '',\n              fullMsg: 'Element <body> was visible after 39 milliseconds.',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Testing if the page title contains \\'Ecosia\\' (7ms)',\n              stackTrace: '',\n              fullMsg: 'Testing if the page title contains \\u001b[0;33m\\'Ecosia\\'\\u001b[0m \\u001b[0;90m(7ms)\\u001b[0m',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Testing if element <input[type=search]> is visible (17ms)',\n              stackTrace: '',\n              fullMsg: 'Testing if element \\u001b[0;33m<input[type=search]>\\u001b[0m is visible \\u001b[0;90m(17ms)\\u001b[0m',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Testing if element <button[type=submit]> is visible (86ms)',\n              stackTrace: '',\n              fullMsg: 'Testing if element \\u001b[0;33m<button[type=submit]>\\u001b[0m is visible \\u001b[0;90m(86ms)\\u001b[0m',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Testing if element <.layout__content> contains text \\'Nightwatch.js\\' (136ms)',\n              stackTrace: '',\n              fullMsg: 'Testing if element \\u001b[0;33m<.layout__content>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(136ms)\\u001b[0m',\n              failure: false\n            }\n          ],\n          commands: [\n          ],\n          passed: 5,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 5,\n          status: 'pass',\n          steps: [\n          ],\n          stackTrace: '',\n          testcases: {\n            'Demo test ecosia.org': {\n              time: '3.056',\n              assertions: [\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Element <body> was visible after 39 milliseconds.',\n                  stackTrace: '',\n                  fullMsg: 'Element <body> was visible after 39 milliseconds.',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Testing if the page title contains \\u001b[0;33m\\'Ecosia\\'\\u001b[0m \\u001b[0;90m(7ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Testing if the page title contains \\u001b[0;33m\\'Ecosia\\'\\u001b[0m \\u001b[0;90m(7ms)\\u001b[0m',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Testing if element \\u001b[0;33m<input[type=search]>\\u001b[0m is visible \\u001b[0;90m(17ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Testing if element \\u001b[0;33m<input[type=search]>\\u001b[0m is visible \\u001b[0;90m(17ms)\\u001b[0m',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Testing if element \\u001b[0;33m<button[type=submit]>\\u001b[0m is visible \\u001b[0;90m(86ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Testing if element \\u001b[0;33m<button[type=submit]>\\u001b[0m is visible \\u001b[0;90m(86ms)\\u001b[0m',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Testing if element \\u001b[0;33m<.layout__content>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(136ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Testing if element \\u001b[0;33m<.layout__content>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(136ms)\\u001b[0m',\n                  failure: false\n                }\n              ],\n              tests: 5,\n              commands: [\n              ],\n              passed: 5,\n              errors: 0,\n              failed: 0,\n              skipped: 0,\n              status: 'pass',\n              steps: [\n              ],\n              stackTrace: '',\n              timeMs: 3056,\n              startTimestamp: 'Thu, 06 Apr 2023 10:18:37 GMT',\n              endTimestamp: 'Thu, 06 Apr 2023 10:18:40 GMT'\n            }\n          },\n          timeMs: 3056,\n          startTimestamp: 'Thu, 06 Apr 2023 10:18:37 GMT',\n          endTimestamp: 'Thu, 06 Apr 2023 10:18:40 GMT'\n        }\n      },\n      completedSections: {\n        __global_beforeEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __before_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'navigateTo',\n              args: [\n                'https://www.ecosia.org/'\n              ],\n              startTime: 1680776313426,\n              endTime: 1680776317581,\n              elapsedTime: 4155,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        'Demo test ecosia.org': {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'waitForElementVisible',\n              args: [\n                'body'\n              ],\n              startTime: 1680776317585,\n              endTime: 1680776317625,\n              elapsedTime: 40,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'assert.titleContains',\n              args: [\n                'Ecosia'\n              ],\n              startTime: 1680776317626,\n              endTime: 1680776317633,\n              elapsedTime: 7,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'assert.visible',\n              args: [\n                'input[type=search]'\n              ],\n              startTime: 1680776317633,\n              endTime: 1680776317653,\n              elapsedTime: 20,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'setValue',\n              args: [\n                'input[type=search]',\n                'nightwatch'\n              ],\n              startTime: 1680776317653,\n              endTime: 1680776317770,\n              elapsedTime: 117,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'assert.visible',\n              args: [\n                'button[type=submit]'\n              ],\n              startTime: 1680776317770,\n              endTime: 1680776317857,\n              elapsedTime: 87,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'click',\n              args: [\n                'button[type=submit]'\n              ],\n              startTime: 1680776317858,\n              endTime: 1680776320498,\n              elapsedTime: 2640,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'assert.textContains',\n              args: [\n                '.layout__content',\n                'Nightwatch.js'\n              ],\n              startTime: 1680776320498,\n              endTime: 1680776320637,\n              elapsedTime: 139,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __after_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'end',\n              args: [\n              ],\n              startTime: 1680776320640,\n              endTime: 1680776320701,\n              elapsedTime: 61,\n              status: 'pass'\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __global_afterEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        }\n      },\n      errmessages: [\n      ],\n      testsCount: 1,\n      skippedCount: 0,\n      failedCount: 0,\n      errorsCount: 0,\n      passedCount: 5,\n      group: '',\n      modulePath: '/examples/tests/ecosia.js',\n      startTimestamp: 'Thu, 06 Apr 2023 10:18:31 GMT',\n      endTimestamp: 'Thu, 06 Apr 2023 10:18:40 GMT',\n      sessionCapabilities: {\n        acceptInsecureCerts: false,\n        browserName: 'chrome',\n        browserVersion: '111.0.5563.146',\n        chrome: {\n          chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n          userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.crT7I3'\n        },\n        'goog:chromeOptions': {\n          debuggerAddress: 'localhost:52878'\n        },\n        networkConnectionEnabled: false,\n        pageLoadStrategy: 'normal',\n        platformName: 'mac os x',\n        proxy: {\n        },\n        setWindowRect: true,\n        strictFileInteractability: false,\n        timeouts: {\n          implicit: 0,\n          pageLoad: 300000,\n          script: 30000\n        },\n        unhandledPromptBehavior: 'dismiss and notify',\n        'webauthn:extension:credBlob': true,\n        'webauthn:extension:largeBlob': true,\n        'webauthn:extension:minPinLength': true,\n        'webauthn:extension:prf': true,\n        'webauthn:virtualAuthenticators': true\n      },\n      sessionId: '5e487662a1e1be6f6d821f923d21af64',\n      projectName: '',\n      buildName: '',\n      testEnv: 'chrome',\n      isMobile: false,\n      status: 'pass',\n      seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/ecosia_chromedriver.log',\n      host: 'localhost',\n      tests: 1,\n      failures: 0,\n      errors: 0,\n      httpOutput: [\n        [\n          '2023-04-06T10:18:31.743Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n          '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:33.414Z',\n          '  Response 200 POST /session (1683ms)',\n          '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.crT7I3&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:52878&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;5e487662a1e1be6f6d821f923d21af64&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:33.429Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/url  </span></b>',\n          '{ url: <span style=\"color:#0A0\">&#39;https://www.ecosia.org/&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.580Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/url (4152ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:18:37.587Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;body&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.604Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (17ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f9443218-7896-44fc-9e32-b7d8642bade8&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.608Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f9443218-7896-44fc-9e32-b7d8642bade8&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;f9443218-7896-44fc-9e32-b7d8642bade8&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.624Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (16ms)',\n          '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.629Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/5e487662a1e1be6f6d821f923d21af64/title  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.632Z',\n          '  Response 200 GET /session/5e487662a1e1be6f6d821f923d21af64/title (4ms)',\n          '{ value: <span style=\"color:#0A0\">&#39;Ecosia - the search engine that plants trees&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.636Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=search]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.641Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (5ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;b51dfbe1-4af2-44cb-85dc-a229a45c3c3f&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.642Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;b51dfbe1-4af2-44cb-85dc-a229a45c3c3f&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;b51dfbe1-4af2-44cb-85dc-a229a45c3c3f&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.651Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (9ms)',\n          '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.654Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=search]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.663Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (9ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;b51dfbe1-4af2-44cb-85dc-a229a45c3c3f&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.664Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/clear  </span></b>',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:18:37.683Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/clear (19ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:18:37.685Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/value  </span></b>',\n          '{\\n     text: <span style=\"color:#0A0\">&#39;nightwatch&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;n&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.769Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/value (84ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:18:37.774Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;button[type=submit]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.843Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (69ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;dfe9ef82-4e7e-407d-b76b-86de1443ac1b&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.847Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;dfe9ef82-4e7e-407d-b76b-86de1443ac1b&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;dfe9ef82-4e7e-407d-b76b-86de1443ac1b&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.855Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (9ms)',\n          '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.860Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;button[type=submit]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.864Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (4ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;dfe9ef82-4e7e-407d-b76b-86de1443ac1b&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:37.865Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/element/dfe9ef82-4e7e-407d-b76b-86de1443ac1b/click  </span></b>',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:18:40.497Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/dfe9ef82-4e7e-407d-b76b-86de1443ac1b/click (2632ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:18:40.501Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;.layout__content&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:40.507Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (6ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;e3557007-ed36-4c86-b27a-7c09e9317276&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:40.509Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/5e487662a1e1be6f6d821f923d21af64/element/e3557007-ed36-4c86-b27a-7c09e9317276/text  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:40.634Z',\n          '  Response 200 GET /session/5e487662a1e1be6f6d821f923d21af64/element/e3557007-ed36-4c86-b27a-7c09e9317276/text (125ms)',\n          '{\\n     value: <span style=\"color:#0A0\">&#39;Search\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;https://nightwatchjs.org\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwatch.js | Node.js powered End-to-End testing framework\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwa...&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:40.643Z',\n          '  Request <b><span style=\"color:#0AA\">DELETE /session/5e487662a1e1be6f6d821f923d21af64  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:40.700Z',\n          '  Response 200 DELETE /session/5e487662a1e1be6f6d821f923d21af64 (57ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ]\n      ],\n      rawHttpOutput: [\n        [\n          '2023-04-06T10:18:31.743Z',\n          '  Request POST /session  ',\n          '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:33.414Z',\n          '  Response 200 POST /session (1683ms)',\n          '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.crT7I3\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:52878\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'5e487662a1e1be6f6d821f923d21af64\\'\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:33.429Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/url  ',\n          '{ url: \\'https://www.ecosia.org/\\' }'\n        ],\n        [\n          '2023-04-06T10:18:37.580Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/url (4152ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:18:37.587Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n          '{ using: \\'css selector\\', value: \\'body\\' }'\n        ],\n        [\n          '2023-04-06T10:18:37.604Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (17ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f9443218-7896-44fc-9e32-b7d8642bade8\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:37.608Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f9443218-7896-44fc-9e32-b7d8642bade8\\',\\n         ELEMENT: \\'f9443218-7896-44fc-9e32-b7d8642bade8\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:37.624Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (16ms)',\n          '{ value: true }'\n        ],\n        [\n          '2023-04-06T10:18:37.629Z',\n          '  Request GET /session/5e487662a1e1be6f6d821f923d21af64/title  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:18:37.632Z',\n          '  Response 200 GET /session/5e487662a1e1be6f6d821f923d21af64/title (4ms)',\n          '{ value: \\'Ecosia - the search engine that plants trees\\' }'\n        ],\n        [\n          '2023-04-06T10:18:37.636Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n          '{ using: \\'css selector\\', value: \\'input[type=search]\\' }'\n        ],\n        [\n          '2023-04-06T10:18:37.641Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (5ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'b51dfbe1-4af2-44cb-85dc-a229a45c3c3f\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:37.642Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'b51dfbe1-4af2-44cb-85dc-a229a45c3c3f\\',\\n         ELEMENT: \\'b51dfbe1-4af2-44cb-85dc-a229a45c3c3f\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:37.651Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (9ms)',\n          '{ value: true }'\n        ],\n        [\n          '2023-04-06T10:18:37.654Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n          '{ using: \\'css selector\\', value: \\'input[type=search]\\' }'\n        ],\n        [\n          '2023-04-06T10:18:37.663Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (9ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'b51dfbe1-4af2-44cb-85dc-a229a45c3c3f\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:37.664Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/clear  ',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:18:37.683Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/clear (19ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:18:37.685Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/value  ',\n          '{\\n     text: \\'nightwatch\\',\\n     value: [\\n       \\'n\\', \\'i\\', \\'g\\', \\'h\\',\\n       \\'t\\', \\'w\\', \\'a\\', \\'t\\',\\n       \\'c\\', \\'h\\'\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:37.769Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/value (84ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:18:37.774Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n          '{ using: \\'css selector\\', value: \\'button[type=submit]\\' }'\n        ],\n        [\n          '2023-04-06T10:18:37.843Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (69ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'dfe9ef82-4e7e-407d-b76b-86de1443ac1b\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:37.847Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'dfe9ef82-4e7e-407d-b76b-86de1443ac1b\\',\\n         ELEMENT: \\'dfe9ef82-4e7e-407d-b76b-86de1443ac1b\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:37.855Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (9ms)',\n          '{ value: true }'\n        ],\n        [\n          '2023-04-06T10:18:37.860Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n          '{ using: \\'css selector\\', value: \\'button[type=submit]\\' }'\n        ],\n        [\n          '2023-04-06T10:18:37.864Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (4ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'dfe9ef82-4e7e-407d-b76b-86de1443ac1b\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:37.865Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/element/dfe9ef82-4e7e-407d-b76b-86de1443ac1b/click  ',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:18:40.497Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/dfe9ef82-4e7e-407d-b76b-86de1443ac1b/click (2632ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:18:40.501Z',\n          '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n          '{ using: \\'css selector\\', value: \\'.layout__content\\' }'\n        ],\n        [\n          '2023-04-06T10:18:40.507Z',\n          '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (6ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'e3557007-ed36-4c86-b27a-7c09e9317276\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:40.509Z',\n          '  Request GET /session/5e487662a1e1be6f6d821f923d21af64/element/e3557007-ed36-4c86-b27a-7c09e9317276/text  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:18:40.634Z',\n          '  Response 200 GET /session/5e487662a1e1be6f6d821f923d21af64/element/e3557007-ed36-4c86-b27a-7c09e9317276/text (125ms)',\n          '{\\n     value: \\'Search\\\\n\\' +\\n       \\'https://nightwatchjs.org\\\\n\\' +\\n       \\'Nightwatch.js | Node.js powered End-to-End testing framework\\\\n\\' +\\n       \\'Nightwa...\\',\\n     suppressBase64Data: true\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:40.643Z',\n          '  Request DELETE /session/5e487662a1e1be6f6d821f923d21af64  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:18:40.700Z',\n          '  Response 200 DELETE /session/5e487662a1e1be6f6d821f923d21af64 (57ms)',\n          '{ value: null }'\n        ]\n      ]\n    },\n    'sample-with-relative-locators': {\n      reportPrefix: 'CHROME_111.0.5563.146__',\n      assertionsCount: 5,\n      lastError: null,\n      skippedAtRuntime: [\n      ],\n      skipped: [\n      ],\n      time: '0.2180',\n      timeMs: 218,\n      completed: {\n        'locate password input': {\n          time: '0.09900',\n          assertions: [\n            {\n              name: 'NightwatchAssertError',\n              message: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n              stackTrace: '',\n              fullMsg: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input (29ms)',\n              stackTrace: '',\n              fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (29ms)\\u001b[0m',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \"password\" (37ms)',\n              stackTrace: '',\n              fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (37ms)\\u001b[0m',\n              failure: false\n            }\n          ],\n          commands: [\n          ],\n          passed: 3,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 3,\n          status: 'pass',\n          steps: [\n          ],\n          stackTrace: '',\n          testcases: {\n            'locate password input': {\n              time: '0.09900',\n              assertions: [\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n                  stackTrace: '',\n                  fullMsg: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (29ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (29ms)\\u001b[0m',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (37ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (37ms)\\u001b[0m',\n                  failure: false\n                }\n              ],\n              tests: 3,\n              commands: [\n              ],\n              passed: 3,\n              errors: 0,\n              failed: 0,\n              skipped: 0,\n              status: 'pass',\n              steps: [\n              ],\n              stackTrace: '',\n              timeMs: 99,\n              startTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n              endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT'\n            }\n          },\n          timeMs: 99,\n          startTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n          endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT'\n        },\n        'fill in password input': {\n          time: '0.1190',\n          assertions: [\n            {\n              name: 'NightwatchAssertError',\n              message: 'Element <form.login-form> was visible after 17 milliseconds.',\n              stackTrace: '',\n              fullMsg: 'Element <form.login-form> was visible after 17 milliseconds.',\n              failure: false\n            },\n            {\n              name: 'NightwatchAssertError',\n              message: 'Testing if value of element <input[type=password]> equals \\'password\\' (11ms)',\n              stackTrace: '',\n              fullMsg: 'Testing if value of element \\u001b[0;33m<input[type=password]>\\u001b[0m equals \\u001b[0;33m\\'password\\'\\u001b[0m \\u001b[0;90m(11ms)\\u001b[0m',\n              failure: false\n            }\n          ],\n          commands: [\n          ],\n          passed: 2,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 2,\n          status: 'pass',\n          steps: [\n          ],\n          stackTrace: '',\n          testcases: {\n            'locate password input': {\n              time: '0.09900',\n              assertions: [\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n                  stackTrace: '',\n                  fullMsg: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (29ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (29ms)\\u001b[0m',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (37ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (37ms)\\u001b[0m',\n                  failure: false\n                }\n              ],\n              tests: 3,\n              commands: [\n              ],\n              passed: 3,\n              errors: 0,\n              failed: 0,\n              skipped: 0,\n              status: 'pass',\n              steps: [\n              ],\n              stackTrace: '',\n              timeMs: 99,\n              startTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n              endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT'\n            },\n            'fill in password input': {\n              time: '0.1190',\n              assertions: [\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Element <form.login-form> was visible after 17 milliseconds.',\n                  stackTrace: '',\n                  fullMsg: 'Element <form.login-form> was visible after 17 milliseconds.',\n                  failure: false\n                },\n                {\n                  name: 'NightwatchAssertError',\n                  message: 'Testing if value of element \\u001b[0;33m<input[type=password]>\\u001b[0m equals \\u001b[0;33m\\'password\\'\\u001b[0m \\u001b[0;90m(11ms)\\u001b[0m',\n                  stackTrace: '',\n                  fullMsg: 'Testing if value of element \\u001b[0;33m<input[type=password]>\\u001b[0m equals \\u001b[0;33m\\'password\\'\\u001b[0m \\u001b[0;90m(11ms)\\u001b[0m',\n                  failure: false\n                }\n              ],\n              tests: 2,\n              commands: [\n              ],\n              passed: 2,\n              errors: 0,\n              failed: 0,\n              skipped: 0,\n              status: 'pass',\n              steps: [\n              ],\n              stackTrace: '',\n              timeMs: 119,\n              startTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n              endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT'\n            }\n          },\n          timeMs: 119,\n          startTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n          endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT'\n        }\n      },\n      completedSections: {\n        __global_beforeEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __before_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'navigateTo',\n              args: [\n                'https://archive.org/account/login'\n              ],\n              startTime: 1680776312360,\n              endTime: 1680776318569,\n              elapsedTime: 6209,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        'locate password input': {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'waitForElementVisible',\n              args: [\n                'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})'\n              ],\n              startTime: 1680776318572,\n              endTime: 1680776318600,\n              elapsedTime: 28,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'expect.element',\n              args: [\n                'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})'\n              ],\n              startTime: 1680776318601,\n              endTime: 1680776318630,\n              elapsedTime: 29,\n              status: 'pass',\n              result: {\n              }\n            },\n            {\n              name: 'expect.element',\n              args: [\n                'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})'\n              ],\n              startTime: 1680776318630,\n              endTime: 1680776318668,\n              elapsedTime: 38,\n              status: 'pass',\n              result: {\n              }\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        'fill in password input': {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'waitForElementVisible',\n              args: [\n                'form.login-form'\n              ],\n              startTime: 1680776318672,\n              endTime: 1680776318689,\n              elapsedTime: 17,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'setValue',\n              args: [\n                'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})',\n                'password'\n              ],\n              startTime: 1680776318689,\n              endTime: 1680776318775,\n              elapsedTime: 86,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            },\n            {\n              name: 'assert.valueEquals',\n              args: [\n                'input[type=password]',\n                'password'\n              ],\n              startTime: 1680776318775,\n              endTime: 1680776318787,\n              elapsedTime: 12,\n              status: 'pass',\n              result: {\n                status: 0\n              }\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __after_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n            {\n              name: 'end',\n              args: [\n              ],\n              startTime: 1680776318790,\n              endTime: 1680776318847,\n              elapsedTime: 57,\n              status: 'pass'\n            }\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        },\n        __global_afterEach_hook: {\n          time: 0,\n          assertions: [\n          ],\n          commands: [\n          ],\n          passed: 0,\n          errors: 0,\n          failed: 0,\n          skipped: 0,\n          tests: 0,\n          status: 'pass'\n        }\n      },\n      errmessages: [\n      ],\n      testsCount: 2,\n      skippedCount: 0,\n      failedCount: 0,\n      errorsCount: 0,\n      passedCount: 5,\n      group: '',\n      modulePath: '/examples/tests/sample-with-relative-locators.js',\n      startTimestamp: 'Thu, 06 Apr 2023 10:18:30 GMT',\n      endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n      sessionCapabilities: {\n        acceptInsecureCerts: false,\n        browserName: 'chrome',\n        browserVersion: '111.0.5563.146',\n        chrome: {\n          chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n          userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.JaFqwI'\n        },\n        'goog:chromeOptions': {\n          debuggerAddress: 'localhost:52856'\n        },\n        networkConnectionEnabled: false,\n        pageLoadStrategy: 'normal',\n        platformName: 'mac os x',\n        proxy: {\n        },\n        setWindowRect: true,\n        strictFileInteractability: false,\n        timeouts: {\n          implicit: 0,\n          pageLoad: 300000,\n          script: 30000\n        },\n        unhandledPromptBehavior: 'dismiss and notify',\n        'webauthn:extension:credBlob': true,\n        'webauthn:extension:largeBlob': true,\n        'webauthn:extension:minPinLength': true,\n        'webauthn:extension:prf': true,\n        'webauthn:virtualAuthenticators': true\n      },\n      sessionId: '00dd2b665dc8d47d951758a8df6aab16',\n      projectName: '',\n      buildName: '',\n      testEnv: 'chrome',\n      isMobile: false,\n      status: 'pass',\n      seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/sample-with-relative-locators_chromedriver.log',\n      host: 'localhost',\n      tests: 2,\n      failures: 0,\n      errors: 0,\n      httpOutput: [\n        [\n          '2023-04-06T10:18:30.901Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n          '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:32.353Z',\n          '  Response 200 POST /session (1454ms)',\n          '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.JaFqwI&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:52856&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;00dd2b665dc8d47d951758a8df6aab16&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:32.362Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/url  </span></b>',\n          '{ url: <span style=\"color:#0A0\">&#39;https://archive.org/account/login&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.567Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/url (6205ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:18:38.576Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.588Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (13ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;627a1655-8ce4-4fe9-9694-bc4027e6ce99&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;68c381f6-bdd6-4553-8fd2-f849a12688fd&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.590Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.599Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (9ms)',\n          '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.603Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.616Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (14ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;627a1655-8ce4-4fe9-9694-bc4027e6ce99&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;68c381f6-bdd6-4553-8fd2-f849a12688fd&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.618Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/name  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.629Z',\n          '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/name (11ms)',\n          '{ value: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.633Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.654Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (22ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;627a1655-8ce4-4fe9-9694-bc4027e6ce99&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;68c381f6-bdd6-4553-8fd2-f849a12688fd&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.656Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/attribute/type  </span></b>',\n          '<span style=\"color:#555\">undefined<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.667Z',\n          '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/attribute/type (12ms)',\n          '{ value: <span style=\"color:#0A0\">&#39;password&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.673Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;form.login-form&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.680Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/elements (8ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;8f46bd5c-745a-47f0-a218-d476c573a5cb&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.682Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;8f46bd5c-745a-47f0-a218-d476c573a5cb&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;8f46bd5c-745a-47f0-a218-d476c573a5cb&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.689Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (7ms)',\n          '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.691Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n          '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.697Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (6ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;627a1655-8ce4-4fe9-9694-bc4027e6ce99&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;68c381f6-bdd6-4553-8fd2-f849a12688fd&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.698Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/clear  </span></b>',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:18:38.713Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/clear (15ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:18:38.714Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/value  </span></b>',\n          '{\\n     text: <span style=\"color:#0A0\">&#39;password&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;p&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;o&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;r&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;d&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.774Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/value (60ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ],\n        [\n          '2023-04-06T10:18:38.778Z',\n          '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/elements  </span></b>',\n          '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=password]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.783Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/elements (5ms)',\n          '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.784Z',\n          '  Request <b><span style=\"color:#0AA\">GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/property/value  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.786Z',\n          '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/property/value (2ms)',\n          '{ value: <span style=\"color:#0A0\">&#39;password&#39;<span style=\"color:#FFF\"> }</span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.793Z',\n          '  Request <b><span style=\"color:#0AA\">DELETE /session/00dd2b665dc8d47d951758a8df6aab16  </span></b>',\n          '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n        ],\n        [\n          '2023-04-06T10:18:38.846Z',\n          '  Response 200 DELETE /session/00dd2b665dc8d47d951758a8df6aab16 (53ms)',\n          '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n        ]\n      ],\n      rawHttpOutput: [\n        [\n          '2023-04-06T10:18:30.901Z',\n          '  Request POST /session  ',\n          '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:32.353Z',\n          '  Response 200 POST /session (1454ms)',\n          '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.JaFqwI\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:52856\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'00dd2b665dc8d47d951758a8df6aab16\\'\\n     }\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:32.362Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/url  ',\n          '{ url: \\'https://archive.org/account/login\\' }'\n        ],\n        [\n          '2023-04-06T10:18:38.567Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/url (6205ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:18:38.576Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.588Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (13ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'627a1655-8ce4-4fe9-9694-bc4027e6ce99\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'68c381f6-bdd6-4553-8fd2-f849a12688fd\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.590Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\',\\n         ELEMENT: \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.599Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (9ms)',\n          '{ value: true }'\n        ],\n        [\n          '2023-04-06T10:18:38.603Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.616Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (14ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'627a1655-8ce4-4fe9-9694-bc4027e6ce99\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'68c381f6-bdd6-4553-8fd2-f849a12688fd\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.618Z',\n          '  Request GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/name  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:18:38.629Z',\n          '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/name (11ms)',\n          '{ value: \\'input\\' }'\n        ],\n        [\n          '2023-04-06T10:18:38.633Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.654Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (22ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'627a1655-8ce4-4fe9-9694-bc4027e6ce99\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'68c381f6-bdd6-4553-8fd2-f849a12688fd\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.656Z',\n          '  Request GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/attribute/type  ',\n          'undefined'\n        ],\n        [\n          '2023-04-06T10:18:38.667Z',\n          '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/attribute/type (12ms)',\n          '{ value: \\'password\\' }'\n        ],\n        [\n          '2023-04-06T10:18:38.673Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/elements  ',\n          '{ using: \\'css selector\\', value: \\'form.login-form\\' }'\n        ],\n        [\n          '2023-04-06T10:18:38.680Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/elements (8ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'8f46bd5c-745a-47f0-a218-d476c573a5cb\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.682Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'8f46bd5c-745a-47f0-a218-d476c573a5cb\\',\\n         ELEMENT: \\'8f46bd5c-745a-47f0-a218-d476c573a5cb\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.689Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (7ms)',\n          '{ value: true }'\n        ],\n        [\n          '2023-04-06T10:18:38.691Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n          '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.697Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (6ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'627a1655-8ce4-4fe9-9694-bc4027e6ce99\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'68c381f6-bdd6-4553-8fd2-f849a12688fd\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.698Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/clear  ',\n          '{}'\n        ],\n        [\n          '2023-04-06T10:18:38.713Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/clear (15ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:18:38.714Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/value  ',\n          '{\\n     text: \\'password\\',\\n     value: [\\n       \\'p\\', \\'a\\', \\'s\\',\\n       \\'s\\', \\'w\\', \\'o\\',\\n       \\'r\\', \\'d\\'\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.774Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/value (60ms)',\n          '{ value: null }'\n        ],\n        [\n          '2023-04-06T10:18:38.778Z',\n          '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/elements  ',\n          '{ using: \\'css selector\\', value: \\'input[type=password]\\' }'\n        ],\n        [\n          '2023-04-06T10:18:38.783Z',\n          '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/elements (5ms)',\n          '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       }\\n     ]\\n  }'\n        ],\n        [\n          '2023-04-06T10:18:38.784Z',\n          '  Request GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/property/value  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:18:38.786Z',\n          '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/property/value (2ms)',\n          '{ value: \\'password\\' }'\n        ],\n        [\n          '2023-04-06T10:18:38.793Z',\n          '  Request DELETE /session/00dd2b665dc8d47d951758a8df6aab16  ',\n          '\\'\\''\n        ],\n        [\n          '2023-04-06T10:18:38.846Z',\n          '  Response 200 DELETE /session/00dd2b665dc8d47d951758a8df6aab16 (53ms)',\n          '{ value: null }'\n        ]\n      ]\n    }\n  },\n  modulesWithEnv: {\n    chrome: {\n      selectElement: {\n        reportPrefix: 'CHROME_111.0.5563.146__',\n        assertionsCount: 1,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '2.865',\n        timeMs: 2865,\n        completed: {\n          demoTest: {\n            time: '2.865',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Forth option is selected (130ms)',\n                stackTrace: '',\n                fullMsg: 'Forth option is selected \\u001b[0;90m(130ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 1,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 1,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              demoTest: {\n                time: '2.865',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Forth option is selected \\u001b[0;90m(130ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Forth option is selected \\u001b[0;90m(130ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 1,\n                commands: [\n                ],\n                passed: 1,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 2865,\n                startTimestamp: 'Thu, 06 Apr 2023 10:18:33 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:18:36 GMT'\n              }\n            },\n            timeMs: 2865,\n            startTimestamp: 'Thu, 06 Apr 2023 10:18:33 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:18:36 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          demoTest: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'url',\n                args: [\n                  'https://www.selenium.dev/selenium/web/formPage.html'\n                ],\n                startTime: 1680776313720,\n                endTime: 1680776316325,\n                elapsedTime: 2605,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'element().getAttribute',\n                args: [\n                  'tagName'\n                ],\n                startTime: 1680776316337,\n                endTime: 1680776316373,\n                elapsedTime: 36,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'element().findElement',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776316374,\n                endTime: 1680776316383,\n                elapsedTime: 9,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'perform',\n                args: [\n                  'function () { [native code] }'\n                ],\n                startTime: 1680776316330,\n                endTime: 1680776316429,\n                elapsedTime: 99,\n                status: 'pass'\n              },\n              {\n                name: 'element().findElement',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776316429,\n                endTime: 1680776316439,\n                elapsedTime: 10,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'assert.selected',\n                args: [\n                  '[object Object]',\n                  'Forth option is selected'\n                ],\n                startTime: 1680776316440,\n                endTime: 1680776316579,\n                elapsedTime: 139,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776316589,\n                endTime: 1680776316663,\n                elapsedTime: 74,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 1,\n        group: '',\n        modulePath: '/examples/tests/selectElement.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:18:31 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:18:36 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'chrome',\n          browserVersion: '111.0.5563.146',\n          chrome: {\n            chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n            userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.sR1HWF'\n          },\n          'goog:chromeOptions': {\n            debuggerAddress: 'localhost:52889'\n          },\n          networkConnectionEnabled: false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac os x',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify',\n          'webauthn:extension:credBlob': true,\n          'webauthn:extension:largeBlob': true,\n          'webauthn:extension:minPinLength': true,\n          'webauthn:extension:prf': true,\n          'webauthn:virtualAuthenticators': true\n        },\n        sessionId: '94e5716f8bba3e2833067803902caa56',\n        projectName: '',\n        buildName: '',\n        testEnv: 'chrome',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/selectElement_chromedriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:18:31.939Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:33.711Z',\n            '  Response 200 POST /session (1771ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.sR1HWF&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:52889&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;94e5716f8bba3e2833067803902caa56&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:33.723Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/94e5716f8bba3e2833067803902caa56/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://www.selenium.dev/selenium/web/formPage.html&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.321Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/url (2598ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:36.340Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/94e5716f8bba3e2833067803902caa56/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;select[name=selectomatic]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.357Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/elements (17ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;89d09eaa-d9de-4096-a147-e9b869129fc5&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.359Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/94e5716f8bba3e2833067803902caa56/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var h=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=h;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (43188 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;89d09eaa-d9de-4096-a147-e9b869129fc5&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;89d09eaa-d9de-4096-a147-e9b869129fc5&#39;<span style=\"color:#FFF\">\\n       },\\n       <span style=\"color:#0A0\">&#39;tagName&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.372Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/execute/sync (13ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;SELECT&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.375Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/94e5716f8bba3e2833067803902caa56/element/89d09eaa-d9de-4096-a147-e9b869129fc5/element  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;xpath&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;./option[. = &quot;Four&quot;]|./option[normalize-space(text()) = &quot;Four&quot;]|./optgroup/option[. = &quot;Four&quot;]|./optgroup/option[normalize-space(text()) = &quot;Four&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.383Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/element/89d09eaa-d9de-4096-a147-e9b869129fc5/element (8ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;5e26d261-54b0-4e9a-8896-4130d2dcb98f&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.384Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/selected  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.397Z',\n            '  Response 200 GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/selected (13ms)',\n            '{ value: <span style=\"color:#A50\">false<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.399Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/enabled  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.407Z',\n            '  Response 200 GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/enabled (8ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.408Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:36.428Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/click (20ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:36.431Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/94e5716f8bba3e2833067803902caa56/element/89d09eaa-d9de-4096-a147-e9b869129fc5/element  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;option[value=four]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.439Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/element/89d09eaa-d9de-4096-a147-e9b869129fc5/element (9ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;5e26d261-54b0-4e9a-8896-4130d2dcb98f&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.497Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/selected  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.570Z',\n            '  Response 200 GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/selected (73ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.594Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/94e5716f8bba3e2833067803902caa56  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.653Z',\n            '  Response 200 DELETE /session/94e5716f8bba3e2833067803902caa56 (59ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:18:31.939Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:33.711Z',\n            '  Response 200 POST /session (1771ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.sR1HWF\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:52889\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'94e5716f8bba3e2833067803902caa56\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:33.723Z',\n            '  Request POST /session/94e5716f8bba3e2833067803902caa56/url  ',\n            '{ url: \\'https://www.selenium.dev/selenium/web/formPage.html\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.321Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/url (2598ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:36.340Z',\n            '  Request POST /session/94e5716f8bba3e2833067803902caa56/elements  ',\n            '{ using: \\'css selector\\', value: \\'select[name=selectomatic]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.357Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/elements (17ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'89d09eaa-d9de-4096-a147-e9b869129fc5\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.359Z',\n            '  Request POST /session/94e5716f8bba3e2833067803902caa56/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var h=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=h;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (43188 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'89d09eaa-d9de-4096-a147-e9b869129fc5\\',\\n         ELEMENT: \\'89d09eaa-d9de-4096-a147-e9b869129fc5\\'\\n       },\\n       \\'tagName\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.372Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/execute/sync (13ms)',\n            '{ value: \\'SELECT\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.375Z',\n            '  Request POST /session/94e5716f8bba3e2833067803902caa56/element/89d09eaa-d9de-4096-a147-e9b869129fc5/element  ',\n            '{\\n     using: \\'xpath\\',\\n     value: \\'./option[. = &quot;Four&quot;]|./option[normalize-space(text()) = &quot;Four&quot;]|./optgroup/option[. = &quot;Four&quot;]|./optgroup/option[normalize-space(text()) = &quot;Four&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.383Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/element/89d09eaa-d9de-4096-a147-e9b869129fc5/element (8ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'5e26d261-54b0-4e9a-8896-4130d2dcb98f\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.384Z',\n            '  Request GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/selected  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:36.397Z',\n            '  Response 200 GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/selected (13ms)',\n            '{ value: false }'\n          ],\n          [\n            '2023-04-06T10:18:36.399Z',\n            '  Request GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/enabled  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:36.407Z',\n            '  Response 200 GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/enabled (8ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:18:36.408Z',\n            '  Request POST /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:36.428Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/click (20ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:36.431Z',\n            '  Request POST /session/94e5716f8bba3e2833067803902caa56/element/89d09eaa-d9de-4096-a147-e9b869129fc5/element  ',\n            '{ using: \\'css selector\\', value: \\'option[value=four]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.439Z',\n            '  Response 200 POST /session/94e5716f8bba3e2833067803902caa56/element/89d09eaa-d9de-4096-a147-e9b869129fc5/element (9ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'5e26d261-54b0-4e9a-8896-4130d2dcb98f\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.497Z',\n            '  Request GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/selected  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:36.570Z',\n            '  Response 200 GET /session/94e5716f8bba3e2833067803902caa56/element/5e26d261-54b0-4e9a-8896-4130d2dcb98f/selected (73ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:18:36.594Z',\n            '  Request DELETE /session/94e5716f8bba3e2833067803902caa56  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:36.653Z',\n            '  Response 200 DELETE /session/94e5716f8bba3e2833067803902caa56 (59ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      chromeCDP_example: {\n        reportPrefix: 'CHROME_111.0.5563.146__',\n        assertionsCount: 1,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '4.659',\n        timeMs: 4659,\n        completed: {\n          'using CDP DOM Snapshot': {\n            time: '4.659',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Passed [deepStrictEqual]: [ \\'documents\\', \\'strings\\' ] deep strict equal [ \\'documents\\', \\'strings\\' ]',\n                stackTrace: '',\n                fullMsg: 'Passed [deepStrictEqual]: [ \\'documents\\', \\'strings\\' ] deep strict equal [ \\'documents\\', \\'strings\\' ]',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 1,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 1,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'using CDP DOM Snapshot': {\n                time: '4.659',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Passed [deepStrictEqual]: [ \\'documents\\', \\'strings\\' ] deep strict equal [ \\'documents\\', \\'strings\\' ]',\n                    stackTrace: '',\n                    fullMsg: 'Passed [deepStrictEqual]: [ \\'documents\\', \\'strings\\' ] deep strict equal [ \\'documents\\', \\'strings\\' ]',\n                    failure: false\n                  }\n                ],\n                tests: 1,\n                commands: [\n                ],\n                passed: 1,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 4659,\n                startTimestamp: 'Thu, 06 Apr 2023 10:18:32 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:18:36 GMT'\n              }\n            },\n            timeMs: 4659,\n            startTimestamp: 'Thu, 06 Apr 2023 10:18:32 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:18:36 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'using CDP DOM Snapshot': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://nightwatchjs.org'\n                ],\n                startTime: 1680776312030,\n                endTime: 1680776316532,\n                elapsedTime: 4502,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'chrome.sendAndGetDevToolsCommand',\n                args: [\n                  'DOMSnapshot.captureSnapshot',\n                  '[object Object]'\n                ],\n                startTime: 1680776316535,\n                endTime: 1680776316678,\n                elapsedTime: 143,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'assert.deepStrictEqual',\n                args: [\n                ],\n                startTime: 1680776316682,\n                endTime: 1680776316683,\n                elapsedTime: 1,\n                status: 'pass',\n                result: {\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776316691,\n                endTime: 1680776316763,\n                elapsedTime: 72,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 1,\n        group: '',\n        modulePath: '/examples/tests/chromeCDP_example.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:18:30 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:18:36 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'chrome',\n          browserVersion: '111.0.5563.146',\n          chrome: {\n            chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n            userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.skcAKm'\n          },\n          'goog:chromeOptions': {\n            debuggerAddress: 'localhost:52846'\n          },\n          networkConnectionEnabled: false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac os x',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify',\n          'webauthn:extension:credBlob': true,\n          'webauthn:extension:largeBlob': true,\n          'webauthn:extension:minPinLength': true,\n          'webauthn:extension:prf': true,\n          'webauthn:virtualAuthenticators': true\n        },\n        sessionId: '763e49ab4471f28def3e033fb0d643bd',\n        projectName: '',\n        buildName: '',\n        testEnv: 'chrome',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/chromeCDP_example_chromedriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:18:30.487Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:32.015Z',\n            '  Response 200 POST /session (1530ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.skcAKm&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:52846&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;763e49ab4471f28def3e033fb0d643bd&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:32.056Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/763e49ab4471f28def3e033fb0d643bd/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://nightwatchjs.org&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.529Z',\n            '  Response 200 POST /session/763e49ab4471f28def3e033fb0d643bd/url (4475ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:36.537Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/763e49ab4471f28def3e033fb0d643bd/chromium/send_command_and_get_result  </span></b>',\n            '{ cmd: <span style=\"color:#0A0\">&#39;DOMSnapshot.captureSnapshot&#39;<span style=\"color:#FFF\">, params: { computedStyles: [] } }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.666Z',\n            '  Response 200 POST /session/763e49ab4471f28def3e033fb0d643bd/chromium/send_command_and_get_result (112ms)',\n            '{\\n     value: {\\n       documents: [\\n         {\\n           baseURL: <span style=\"color:#A50\">0<span style=\"color:#FFF\">,\\n           contentHeight: <span style=\"color:#A50\">3974<span style=\"color:#FFF\">,\\n           contentLanguage: <span style=\"color:#A50\">-1<span style=\"color:#FFF\">,\\n           contentWidth: <span style=\"color:#A50\">1185<span style=\"color:#FFF\">,\\n           documentURL: <span style=\"color:#A50\">0<span style=\"color:#FFF\">,\\n           encodingName: <span style=\"color:#A50\">2<span style=\"color:#FFF\">,\\n           frameId: <span style=\"color:#A50\">3<span style=\"color:#FFF\">,\\n           layout: {\\n             bounds: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             nodeIndex: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             stackingContexts: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             styles: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             text: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">\\n           },\\n           nodes: {\\n             attributes: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             backendNodeId: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             contentDocumentIndex: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             currentSourceURL: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             inputChecked: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             inputValue: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             isClickable: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             nodeName: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             nodeType: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             nodeValue: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             optionSelected: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             originURL: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             parentIndex: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             pseudoIdentifier: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             pseudoType: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             shadowRootType: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             textValue: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">\\n           },\\n           publicId: <span style=\"color:#A50\">-1<span style=\"color:#FFF\">,\\n           scrollOffsetX: <span style=\"color:#A50\">0<span style=\"color:#FFF\">,\\n           scrollOffsetY: <span style=\"color:#A50\">0<span style=\"color:#FFF\">,\\n           systemId: <span style=\"color:#A50\">-1<span style=\"color:#FFF\">,\\n           textBoxes: {\\n             bounds: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             layoutIndex: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             length: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             start: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">\\n           },\\n           title: <span style=\"color:#A50\">1<span style=\"color:#FFF\">\\n         },\\n         {\\n           baseURL: <span style=\"color:#A50\">0<span style=\"color:#FFF\">,\\n           contentHeight: <span style=\"color:#A50\">125<span style=\"color:#FFF\">,\\n           contentLanguage: <span style=\"color:#A50\">-1<span style=\"color:#FFF\">,\\n           contentWidth: <span style=\"color:#A50\">275<span style=\"color:#FFF\">,\\n           documentURL: <span style=\"color:#A50\">695<span style=\"color:#FFF\">,\\n           encodingName: <span style=\"color:#A50\">2<span style=\"color:#FFF\">,\\n           frameId: <span style=\"color:#A50\">696<span style=\"color:#FFF\">,\\n           layout: {\\n             bounds: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             nodeIndex: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             stackingContexts: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             styles: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             text: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">\\n           },\\n           nodes: {\\n             attributes: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             backendNodeId: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             contentDocumentIndex: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             currentSourceURL: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             inputChecked: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             inputValue: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             isClickable: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             nodeName: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             nodeType: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             nodeValue: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             optionSelected: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             originURL: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             parentIndex: <span style=\"color:#0AA\">[Array]<span style=\"color:#FFF\">,\\n             pseudoIdentifier: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             pseudoType: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             shadowRootType: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">,\\n             textValue: <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\">\\n           },\\n           publicId: <span style=\"color:#A50\">-1<span style=\"color:#FFF\">,\\n           scrollOffsetX: <span style=\"color:#A50\">0<span style=\"color:#FFF\">,\\n           scrollOffsetY: <span style=\"color:#A50\">0<span style=\"color:#FFF\">,\\n           systemId: <span style=\"color:#A50\">-1<span style=\"color:#FFF\">,\\n           textBoxes: { bounds: [], layoutIndex: [], length: [], start: [] },\\n           title: <span style=\"color:#A50\">-1<span style=\"color:#FFF\">\\n         }\\n       ],\\n       strings: [\\n         <span style=\"color:#0A0\">&#39;https://nightwatchjs.org/&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;Nightwatch.js | Node.js powered End-to-End testing framework&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;UTF-8&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;5C751C5A821E5E78F3EBEACD0F8DB3AE&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;#document&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;html&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;HTML&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;lang&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;en&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;data-uri&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;HEAD&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;#text&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;\\\\n  &#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;META&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;charset&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;utf-8&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;\\\\n&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;TITLE&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;name&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;description&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;content&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;Write efficient end-to-end tests in Node.js and run them against W3C WebDriver.&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;http-equiv&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;X-UA-Compatible&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;IE=edge&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;viewport&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;width=device-width, initial-scale=1, shrink-to-fit=no&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;\\\\n\\\\n&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;property&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;og:title&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;Nightwatch.js |  Node.js powered End-to-End testing framework&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;og:image&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/img/banners/nightwatch.jpg&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;og:site_name&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;Nightwatch.js&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;og:type&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;website&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;og:description&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;og:url&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;twitter:title&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;twitter:description&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;twitter:image&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;twitter:card&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;summary_large_image&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;twitter:site&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;@nightwatchjs&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;twitter:creator&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;referrer&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;no-referrer-when-downgrade&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;google-site-verification&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;LGNZ66nvi-gru5DR_bV3jry2hqvlMoijhdWZkVT41ZM&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;docsearch:language&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;docsearch:version&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;1.0.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;LINK&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;rel&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;preconnect&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;href&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;https://fonts.googleapis.com&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;https://fonts.gstatic.com&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;crossorigin&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;SCRIPT&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;type&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;text/javascript&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;async&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;src&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;https://www.googletagmanager.com/gtag/js?id=G-NJ5GYXJRCQ&amp;l=dataLayer&amp;cx=c&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;(function(p,h) {\\\\n&#39;<span style=\"color:#FFF\"> +\\n           <span style=\"color:#0A0\">&quot;  p=p.replace(/\\\\\\\\/api\\\\\\\\/.+\\\\\\\\.html$/,&#39;/api/$method&#39;);\\\\n&quot;<span style=\"color:#FFF\"> +\\n           <span style=\"color:#0A0\">&quot;  p=p.replace(/\\\\\\\\/blog\\\\\\\\/.+\\\\\\\\.html$/,&#39;/blog/article&#39;);\\\\n&quot;<span style=\"color:#FFF\"> +\\n           <span style=\"color:#0A0\">&quot;  var q = p.split(&#39;/&#39;); q.shift();\\\\n&quot;<span style=\"color:#FFF\"> +\\n           <span style=\"color:#0A0\">&quot;  h.setAttribute(&#39;data-uri&#39;,(p!=&#39;/&#39;?&#39;/&#39;+q.join(&#39;/&#39;):p));\\\\n&quot;<span style=\"color:#FFF\"> +\\n           <span style=\"color:#0A0\">&#39;})(location.pathname,document.documentElement);\\\\n&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&quot;\\\\n  document.domain = &#39;nightwatchjs.org&#39;;\\\\n&quot;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/css/themes/prism.css&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;stylesheet&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;integrity&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;anonymous&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/css/main.css?v=1103522931&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/css/sidebar.css?v=1103521931&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/css/style.css?v=1103620931&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/css/mobile.css&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/css/docsearch.css&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700;1,900&amp;display=swap&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;data-tag&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;font&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;900&amp;display=swap&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;https://fonts.googleapis.com/css2?family=Spartan:wght@500;600;700&amp;display=swap&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/css/style1.css?v=1103620931&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/css/desktop.css?v=1103620931&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/css/tablet.css?v=1103620931&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;/css/mobile1.css?v=1103620931&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;https://unpkg.com/@stackblitz/sdk@1.8.2/bundles/sdk.umd.js&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;#comment&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39; Adding synchronous VWO snippet to  prevent flickering issue &#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;https://dev.visualwebsiteoptimizer.com/lib/366135.js&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;id&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;vwoCode&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;onerror&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;window.vwoSyncTpcFailed=true&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;https://dev.visualwebsiteoptimizer.com/tpc?a=366135&amp;r=0.7714095575006725&#39;<span style=\"color:#FFF\">,\\n         ... 597 more items\\n       ]\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.696Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/763e49ab4471f28def3e033fb0d643bd  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.756Z',\n            '  Response 200 DELETE /session/763e49ab4471f28def3e033fb0d643bd (59ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:18:30.487Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:32.015Z',\n            '  Response 200 POST /session (1530ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.skcAKm\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:52846\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'763e49ab4471f28def3e033fb0d643bd\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:32.056Z',\n            '  Request POST /session/763e49ab4471f28def3e033fb0d643bd/url  ',\n            '{ url: \\'https://nightwatchjs.org\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.529Z',\n            '  Response 200 POST /session/763e49ab4471f28def3e033fb0d643bd/url (4475ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:36.537Z',\n            '  Request POST /session/763e49ab4471f28def3e033fb0d643bd/chromium/send_command_and_get_result  ',\n            '{ cmd: \\'DOMSnapshot.captureSnapshot\\', params: { computedStyles: [] } }'\n          ],\n          [\n            '2023-04-06T10:18:36.666Z',\n            '  Response 200 POST /session/763e49ab4471f28def3e033fb0d643bd/chromium/send_command_and_get_result (112ms)',\n            '{\\n     value: {\\n       documents: [\\n         {\\n           baseURL: 0,\\n           contentHeight: 3974,\\n           contentLanguage: -1,\\n           contentWidth: 1185,\\n           documentURL: 0,\\n           encodingName: 2,\\n           frameId: 3,\\n           layout: {\\n             bounds: [Array],\\n             nodeIndex: [Array],\\n             stackingContexts: [Object],\\n             styles: [Array],\\n             text: [Array]\\n           },\\n           nodes: {\\n             attributes: [Array],\\n             backendNodeId: [Array],\\n             contentDocumentIndex: [Object],\\n             currentSourceURL: [Object],\\n             inputChecked: [Object],\\n             inputValue: [Object],\\n             isClickable: [Object],\\n             nodeName: [Array],\\n             nodeType: [Array],\\n             nodeValue: [Array],\\n             optionSelected: [Object],\\n             originURL: [Object],\\n             parentIndex: [Array],\\n             pseudoIdentifier: [Object],\\n             pseudoType: [Object],\\n             shadowRootType: [Object],\\n             textValue: [Object]\\n           },\\n           publicId: -1,\\n           scrollOffsetX: 0,\\n           scrollOffsetY: 0,\\n           systemId: -1,\\n           textBoxes: {\\n             bounds: [Array],\\n             layoutIndex: [Array],\\n             length: [Array],\\n             start: [Array]\\n           },\\n           title: 1\\n         },\\n         {\\n           baseURL: 0,\\n           contentHeight: 125,\\n           contentLanguage: -1,\\n           contentWidth: 275,\\n           documentURL: 695,\\n           encodingName: 2,\\n           frameId: 696,\\n           layout: {\\n             bounds: [Array],\\n             nodeIndex: [Array],\\n             stackingContexts: [Object],\\n             styles: [Array],\\n             text: [Array]\\n           },\\n           nodes: {\\n             attributes: [Array],\\n             backendNodeId: [Array],\\n             contentDocumentIndex: [Object],\\n             currentSourceURL: [Object],\\n             inputChecked: [Object],\\n             inputValue: [Object],\\n             isClickable: [Object],\\n             nodeName: [Array],\\n             nodeType: [Array],\\n             nodeValue: [Array],\\n             optionSelected: [Object],\\n             originURL: [Object],\\n             parentIndex: [Array],\\n             pseudoIdentifier: [Object],\\n             pseudoType: [Object],\\n             shadowRootType: [Object],\\n             textValue: [Object]\\n           },\\n           publicId: -1,\\n           scrollOffsetX: 0,\\n           scrollOffsetY: 0,\\n           systemId: -1,\\n           textBoxes: { bounds: [], layoutIndex: [], length: [], start: [] },\\n           title: -1\\n         }\\n       ],\\n       strings: [\\n         \\'https://nightwatchjs.org/\\',\\n         \\'Nightwatch.js | Node.js powered End-to-End testing framework\\',\\n         \\'UTF-8\\',\\n         \\'5C751C5A821E5E78F3EBEACD0F8DB3AE\\',\\n         \\'#document\\',\\n         \\'html\\',\\n         \\'HTML\\',\\n         \\'lang\\',\\n         \\'en\\',\\n         \\'data-uri\\',\\n         \\'/\\',\\n         \\'HEAD\\',\\n         \\'#text\\',\\n         \\'\\\\n  \\',\\n         \\'META\\',\\n         \\'charset\\',\\n         \\'utf-8\\',\\n         \\'\\\\n\\',\\n         \\'TITLE\\',\\n         \\'name\\',\\n         \\'description\\',\\n         \\'content\\',\\n         \\'Write efficient end-to-end tests in Node.js and run them against W3C WebDriver.\\',\\n         \\'http-equiv\\',\\n         \\'X-UA-Compatible\\',\\n         \\'IE=edge\\',\\n         \\'viewport\\',\\n         \\'width=device-width, initial-scale=1, shrink-to-fit=no\\',\\n         \\'\\\\n\\\\n\\',\\n         \\'property\\',\\n         \\'og:title\\',\\n         \\'Nightwatch.js |  Node.js powered End-to-End testing framework\\',\\n         \\'og:image\\',\\n         \\'/img/banners/nightwatch.jpg\\',\\n         \\'og:site_name\\',\\n         \\'Nightwatch.js\\',\\n         \\'og:type\\',\\n         \\'website\\',\\n         \\'og:description\\',\\n         \\'og:url\\',\\n         \\'twitter:title\\',\\n         \\'twitter:description\\',\\n         \\'twitter:image\\',\\n         \\'twitter:card\\',\\n         \\'summary_large_image\\',\\n         \\'twitter:site\\',\\n         \\'@nightwatchjs\\',\\n         \\'twitter:creator\\',\\n         \\'referrer\\',\\n         \\'no-referrer-when-downgrade\\',\\n         \\'google-site-verification\\',\\n         \\'LGNZ66nvi-gru5DR_bV3jry2hqvlMoijhdWZkVT41ZM\\',\\n         \\'docsearch:language\\',\\n         \\'docsearch:version\\',\\n         \\'1.0.0\\',\\n         \\'LINK\\',\\n         \\'rel\\',\\n         \\'preconnect\\',\\n         \\'href\\',\\n         \\'https://fonts.googleapis.com\\',\\n         \\'https://fonts.gstatic.com\\',\\n         \\'crossorigin\\',\\n         \\'SCRIPT\\',\\n         \\'type\\',\\n         \\'text/javascript\\',\\n         \\'async\\',\\n         \\'src\\',\\n         \\'https://www.googletagmanager.com/gtag/js?id=G-NJ5GYXJRCQ&amp;l=dataLayer&amp;cx=c\\',\\n         \\'(function(p,h) {\\\\n\\' +\\n           &quot;  p=p.replace(/\\\\\\\\/api\\\\\\\\/.+\\\\\\\\.html$/,\\'/api/$method\\');\\\\n&quot; +\\n           &quot;  p=p.replace(/\\\\\\\\/blog\\\\\\\\/.+\\\\\\\\.html$/,\\'/blog/article\\');\\\\n&quot; +\\n           &quot;  var q = p.split(\\'/\\'); q.shift();\\\\n&quot; +\\n           &quot;  h.setAttribute(\\'data-uri\\',(p!=\\'/\\'?\\'/\\'+q.join(\\'/\\'):p));\\\\n&quot; +\\n           \\'})(location.pathname,document.documentElement);\\\\n\\',\\n         &quot;\\\\n  document.domain = \\'nightwatchjs.org\\';\\\\n&quot;,\\n         \\'/css/themes/prism.css\\',\\n         \\'stylesheet\\',\\n         \\'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css\\',\\n         \\'integrity\\',\\n         \\'sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3\\',\\n         \\'anonymous\\',\\n         \\'/css/main.css?v=1103522931\\',\\n         \\'/css/sidebar.css?v=1103521931\\',\\n         \\'/css/style.css?v=1103620931\\',\\n         \\'/css/mobile.css\\',\\n         \\'/css/docsearch.css\\',\\n         \\'https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700;1,900&amp;display=swap\\',\\n         \\'data-tag\\',\\n         \\'font\\',\\n         \\'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;900&amp;display=swap\\',\\n         \\'https://fonts.googleapis.com/css2?family=Spartan:wght@500;600;700&amp;display=swap\\',\\n         \\'/css/style1.css?v=1103620931\\',\\n         \\'/css/desktop.css?v=1103620931\\',\\n         \\'/css/tablet.css?v=1103620931\\',\\n         \\'/css/mobile1.css?v=1103620931\\',\\n         \\'//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js\\',\\n         \\'https://unpkg.com/@stackblitz/sdk@1.8.2/bundles/sdk.umd.js\\',\\n         \\'#comment\\',\\n         \\' Adding synchronous VWO snippet to  prevent flickering issue \\',\\n         \\'https://dev.visualwebsiteoptimizer.com/lib/366135.js\\',\\n         \\'id\\',\\n         \\'vwoCode\\',\\n         \\'onerror\\',\\n         \\'window.vwoSyncTpcFailed=true\\',\\n         \\'https://dev.visualwebsiteoptimizer.com/tpc?a=366135&amp;r=0.7714095575006725\\',\\n         ... 597 more items\\n       ]\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.696Z',\n            '  Request DELETE /session/763e49ab4471f28def3e033fb0d643bd  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:36.756Z',\n            '  Response 200 DELETE /session/763e49ab4471f28def3e033fb0d643bd (59ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      angularTodoTest: {\n        reportPrefix: 'CHROME_111.0.5563.146__',\n        assertionsCount: 2,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '3.868',\n        timeMs: 3868,\n        completed: {\n          'should add a todo using custom commands': {\n            time: '3.868',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected element <web element{eb6ac9cd-78c6-4755-befd-add49d3d25f4}> text to equal: \"what is nightwatch?\" (14ms)',\n                stackTrace: '',\n                fullMsg: 'Expected element <web element{eb6ac9cd-78c6-4755-befd-add49d3d25f4}> text to equal: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (14ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \"2\" (11ms)',\n                stackTrace: '',\n                fullMsg: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \\u001b[0;33m\"2\"\\u001b[0m\\u001b[0;90m (11ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 2,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 2,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'should add a todo using custom commands': {\n                time: '3.868',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <web element{eb6ac9cd-78c6-4755-befd-add49d3d25f4}> text to equal: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (14ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <web element{eb6ac9cd-78c6-4755-befd-add49d3d25f4}> text to equal: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (14ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \\u001b[0;33m\"2\"\\u001b[0m\\u001b[0;90m (11ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \\u001b[0;33m\"2\"\\u001b[0m\\u001b[0;90m (11ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 2,\n                commands: [\n                ],\n                passed: 2,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 3868,\n                startTimestamp: 'Thu, 06 Apr 2023 10:18:32 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:18:36 GMT'\n              }\n            },\n            timeMs: 3868,\n            startTimestamp: 'Thu, 06 Apr 2023 10:18:32 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:18:36 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'should add a todo using custom commands': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://angularjs.org'\n                ],\n                startTime: 1680776312935,\n                endTime: 1680776315920,\n                elapsedTime: 2985,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'sendKeys',\n                args: [\n                  '[ng-model=\"todoList.todoText\"]',\n                  'what is nightwatch?'\n                ],\n                startTime: 1680776315922,\n                endTime: 1680776316268,\n                elapsedTime: 346,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'click',\n                args: [\n                  '[value=\"add\"]'\n                ],\n                startTime: 1680776316269,\n                endTime: 1680776316537,\n                elapsedTime: 268,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'getElementsInList',\n                args: [\n                  'todoList.todos'\n                ],\n                startTime: 1680776316537,\n                endTime: 1680776316724,\n                elapsedTime: 187,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'expect.element',\n                args: [\n                  'web element{eb6ac9cd-78c6-4755-befd-add49d3d25f4}'\n                ],\n                startTime: 1680776316730,\n                endTime: 1680776316744,\n                elapsedTime: 14,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'element().findElement',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776316745,\n                endTime: 1680776316759,\n                elapsedTime: 14,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'click',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776316761,\n                endTime: 1680776316784,\n                elapsedTime: 23,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'expect.elements',\n                args: [\n                  '*[module=todoApp] li .done-true'\n                ],\n                startTime: 1680776316785,\n                endTime: 1680776316797,\n                elapsedTime: 12,\n                status: 'pass',\n                result: {\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776316804,\n                endTime: 1680776316866,\n                elapsedTime: 62,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 2,\n        group: '',\n        modulePath: '/examples/tests/angularTodoTest.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:18:31 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:18:36 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'chrome',\n          browserVersion: '111.0.5563.146',\n          chrome: {\n            chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n            userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.M6WcDk'\n          },\n          'goog:chromeOptions': {\n            debuggerAddress: 'localhost:52862'\n          },\n          networkConnectionEnabled: false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac os x',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify',\n          'webauthn:extension:credBlob': true,\n          'webauthn:extension:largeBlob': true,\n          'webauthn:extension:minPinLength': true,\n          'webauthn:extension:prf': true,\n          'webauthn:virtualAuthenticators': true\n        },\n        sessionId: 'e5d3ec370d703ed8b3e183646feca185',\n        projectName: '',\n        buildName: '',\n        testEnv: 'chrome',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/angularTodoTest_chromedriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:18:31.172Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:32.923Z',\n            '  Response 200 POST /session (1754ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.M6WcDk&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:52862&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;e5d3ec370d703ed8b3e183646feca185&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:32.937Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e5d3ec370d703ed8b3e183646feca185/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://angularjs.org&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:35.916Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/url (2979ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:35.934Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e5d3ec370d703ed8b3e183646feca185/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[ng-model=&quot;todoList.todoText&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.081Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/elements (149ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;c50fa868-aafd-473a-a56c-95ffaf96d2cf&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.084Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e5d3ec370d703ed8b3e183646feca185/element/c50fa868-aafd-473a-a56c-95ffaf96d2cf/value  </span></b>',\n            '{\\n     text: <span style=\"color:#0A0\">&#39;what is nightwatch?&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;n&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;?&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.267Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/element/c50fa868-aafd-473a-a56c-95ffaf96d2cf/value (184ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:36.271Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e5d3ec370d703ed8b3e183646feca185/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[value=&quot;add&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.287Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/elements (17ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;525d123b-4f69-4d7b-ab2b-003108e17304&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.290Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e5d3ec370d703ed8b3e183646feca185/element/525d123b-4f69-4d7b-ab2b-003108e17304/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:36.536Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/element/525d123b-4f69-4d7b-ab2b-003108e17304/click (246ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:36.540Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e5d3ec370d703ed8b3e183646feca185/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;var passedArgs = Array.prototype.slice.call(arguments,0); return (function(listName) {\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;      // executed in the browser context\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;      // eslint-disable-next-line\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;      var elements = document.querySel... (366 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [ <span style=\"color:#0A0\">&#39;todoList.todos&#39;<span style=\"color:#FFF\"> ]\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.723Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/execute/sync (183ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;2e22efb9-0a46-4516-81b0-a993c7c989f3&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;4f63fa26-dfdc-45c1-97a0-15dc316f826d&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;eb6ac9cd-78c6-4755-befd-add49d3d25f4&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.732Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/e5d3ec370d703ed8b3e183646feca185/element/eb6ac9cd-78c6-4755-befd-add49d3d25f4/text  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.742Z',\n            '  Response 200 GET /session/e5d3ec370d703ed8b3e183646feca185/element/eb6ac9cd-78c6-4755-befd-add49d3d25f4/text (11ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;what is nightwatch?&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.746Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e5d3ec370d703ed8b3e183646feca185/element/eb6ac9cd-78c6-4755-befd-add49d3d25f4/element  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.758Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/element/eb6ac9cd-78c6-4755-befd-add49d3d25f4/element (12ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;e8e3ad00-c40d-454a-b04c-c8f8480f1cc9&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.762Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e5d3ec370d703ed8b3e183646feca185/element/e8e3ad00-c40d-454a-b04c-c8f8480f1cc9/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:36.784Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/element/e8e3ad00-c40d-454a-b04c-c8f8480f1cc9/click (22ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:36.786Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e5d3ec370d703ed8b3e183646feca185/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;*[module=todoApp] li .done-true&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.796Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/elements (10ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ed8be05e-d30f-41c0-abc9-de5cf301c122&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;53da4b20-ed6f-47f0-ad0f-fd48a68edfe7&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.808Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/e5d3ec370d703ed8b3e183646feca185  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.863Z',\n            '  Response 200 DELETE /session/e5d3ec370d703ed8b3e183646feca185 (55ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:18:31.172Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:32.923Z',\n            '  Response 200 POST /session (1754ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.M6WcDk\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:52862\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'e5d3ec370d703ed8b3e183646feca185\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:32.937Z',\n            '  Request POST /session/e5d3ec370d703ed8b3e183646feca185/url  ',\n            '{ url: \\'https://angularjs.org\\' }'\n          ],\n          [\n            '2023-04-06T10:18:35.916Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/url (2979ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:35.934Z',\n            '  Request POST /session/e5d3ec370d703ed8b3e183646feca185/elements  ',\n            '{ using: \\'css selector\\', value: \\'[ng-model=&quot;todoList.todoText&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.081Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/elements (149ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'c50fa868-aafd-473a-a56c-95ffaf96d2cf\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.084Z',\n            '  Request POST /session/e5d3ec370d703ed8b3e183646feca185/element/c50fa868-aafd-473a-a56c-95ffaf96d2cf/value  ',\n            '{\\n     text: \\'what is nightwatch?\\',\\n     value: [\\n       \\'w\\', \\'h\\', \\'a\\', \\'t\\', \\' \\',\\n       \\'i\\', \\'s\\', \\' \\', \\'n\\', \\'i\\',\\n       \\'g\\', \\'h\\', \\'t\\', \\'w\\', \\'a\\',\\n       \\'t\\', \\'c\\', \\'h\\', \\'?\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.267Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/element/c50fa868-aafd-473a-a56c-95ffaf96d2cf/value (184ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:36.271Z',\n            '  Request POST /session/e5d3ec370d703ed8b3e183646feca185/elements  ',\n            '{ using: \\'css selector\\', value: \\'[value=&quot;add&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.287Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/elements (17ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'525d123b-4f69-4d7b-ab2b-003108e17304\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.290Z',\n            '  Request POST /session/e5d3ec370d703ed8b3e183646feca185/element/525d123b-4f69-4d7b-ab2b-003108e17304/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:36.536Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/element/525d123b-4f69-4d7b-ab2b-003108e17304/click (246ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:36.540Z',\n            '  Request POST /session/e5d3ec370d703ed8b3e183646feca185/execute/sync  ',\n            '{\\n     script: \\'var passedArgs = Array.prototype.slice.call(arguments,0); return (function(listName) {\\\\n\\' +\\n       \\'      // executed in the browser context\\\\n\\' +\\n       \\'      // eslint-disable-next-line\\\\n\\' +\\n       \\'      var elements = document.querySel... (366 characters)\\',\\n     args: [ \\'todoList.todos\\' ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.723Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/execute/sync (183ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'2e22efb9-0a46-4516-81b0-a993c7c989f3\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'4f63fa26-dfdc-45c1-97a0-15dc316f826d\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'eb6ac9cd-78c6-4755-befd-add49d3d25f4\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.732Z',\n            '  Request GET /session/e5d3ec370d703ed8b3e183646feca185/element/eb6ac9cd-78c6-4755-befd-add49d3d25f4/text  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:36.742Z',\n            '  Response 200 GET /session/e5d3ec370d703ed8b3e183646feca185/element/eb6ac9cd-78c6-4755-befd-add49d3d25f4/text (11ms)',\n            '{ value: \\'what is nightwatch?\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.746Z',\n            '  Request POST /session/e5d3ec370d703ed8b3e183646feca185/element/eb6ac9cd-78c6-4755-befd-add49d3d25f4/element  ',\n            '{ using: \\'css selector\\', value: \\'input\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.758Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/element/eb6ac9cd-78c6-4755-befd-add49d3d25f4/element (12ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'e8e3ad00-c40d-454a-b04c-c8f8480f1cc9\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.762Z',\n            '  Request POST /session/e5d3ec370d703ed8b3e183646feca185/element/e8e3ad00-c40d-454a-b04c-c8f8480f1cc9/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:36.784Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/element/e8e3ad00-c40d-454a-b04c-c8f8480f1cc9/click (22ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:36.786Z',\n            '  Request POST /session/e5d3ec370d703ed8b3e183646feca185/elements  ',\n            '{ using: \\'css selector\\', value: \\'*[module=todoApp] li .done-true\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.796Z',\n            '  Response 200 POST /session/e5d3ec370d703ed8b3e183646feca185/elements (10ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ed8be05e-d30f-41c0-abc9-de5cf301c122\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'53da4b20-ed6f-47f0-ad0f-fd48a68edfe7\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:36.808Z',\n            '  Request DELETE /session/e5d3ec370d703ed8b3e183646feca185  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:36.863Z',\n            '  Response 200 DELETE /session/e5d3ec370d703ed8b3e183646feca185 (55ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      duckDuckGo: {\n        reportPrefix: 'CHROME_111.0.5563.146__',\n        assertionsCount: 1,\n        lastError: {\n          name: 'NightwatchAssertError',\n          message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5108ms)\\u001b[0m',\n          showDiff: false,\n          abortOnFailure: true,\n          waitFor: true,\n          stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)'\n        },\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '8.932',\n        timeMs: 8932,\n        completed: {\n          'Search Nightwatch.js and check results': {\n            time: '8.932',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \"visible\" but got: \"not found\" (5108ms)',\n                stackTrace: '    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n                fullMsg: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5108ms)\\u001b[0m',\n                failure: 'Expected \"visible\" but got: \"not found\"',\n                screenshots: [\n                  '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154840-GMT+0530.png'\n                ]\n              }\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 1,\n            skipped: 0,\n            tests: 1,\n            status: 'fail',\n            steps: [\n            ],\n            stackTrace: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n            testcases: {\n              'Search Nightwatch.js and check results': {\n                time: '8.932',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5108ms)\\u001b[0m',\n                    stackTrace: '    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n                    fullMsg: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5108ms)\\u001b[0m',\n                    failure: 'Expected \"visible\" but got: \"not found\"',\n                    screenshots: [\n                      '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154840-GMT+0530.png'\n                    ]\n                  }\n                ],\n                tests: 1,\n                commands: [\n                ],\n                passed: 0,\n                errors: 0,\n                failed: 1,\n                skipped: 0,\n                status: 'fail',\n                steps: [\n                ],\n                stackTrace: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n                lastError: {\n                  name: 'NightwatchAssertError',\n                  message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5108ms)\\u001b[0m',\n                  showDiff: false,\n                  abortOnFailure: true,\n                  waitFor: true,\n                  stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)'\n                },\n                timeMs: 8932,\n                startTimestamp: 'Thu, 06 Apr 2023 10:18:31 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:18:40 GMT'\n              }\n            },\n            lastError: {\n              name: 'NightwatchAssertError',\n              message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5108ms)\\u001b[0m',\n              showDiff: false,\n              abortOnFailure: true,\n              waitFor: true,\n              stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)'\n            },\n            timeMs: 8932,\n            startTimestamp: 'Thu, 06 Apr 2023 10:18:31 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:18:40 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'Search Nightwatch.js and check results': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://duckduckgo.com'\n                ],\n                startTime: 1680776311602,\n                endTime: 1680776315235,\n                elapsedTime: 3633,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  '#search_form_input_homepage'\n                ],\n                startTime: 1680776315238,\n                endTime: 1680776320353,\n                elapsedTime: 5115,\n                status: 'fail',\n                result: {\n                  message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \"visible\" but got: \"not found\" (5108ms)',\n                  showDiff: false,\n                  name: 'NightwatchAssertError',\n                  abortOnFailure: true,\n                  stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n                  beautifiedStack: {\n                    filePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js',\n                    error_line_number: 8,\n                    codeSnippet: [\n                      {\n                        line_number: 6,\n                        code: '    browser'\n                      },\n                      {\n                        line_number: 7,\n                        code: '      .navigateTo(\\'https://duckduckgo.com\\')'\n                      },\n                      {\n                        line_number: 8,\n                        code: '      .waitForElementVisible(\\'#search_form_input_homepage\\')'\n                      },\n                      {\n                        line_number: 9,\n                        code: '      .sendKeys(\\'#search_form_input_homepage\\', [\\'Nightwatch.js\\'])'\n                      },\n                      {\n                        line_number: 10,\n                        code: '      .click(\\'#search_button_homepage\\')'\n                      }\n                    ]\n                  }\n                },\n                screenshot: '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154840-GMT+0530.png'\n              },\n              {\n                name: 'saveScreenshot',\n                args: [\n                  '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154840-GMT+0530.png',\n                  'function () { [native code] }'\n                ],\n                startTime: 1680776320407,\n                endTime: 1680776320529,\n                elapsedTime: 122,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'fail'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776320533,\n                endTime: 1680776320599,\n                elapsedTime: 66,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 1,\n        errorsCount: 0,\n        passedCount: 0,\n        group: '',\n        modulePath: '/examples/tests/duckDuckGo.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:18:29 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:18:40 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'chrome',\n          browserVersion: '111.0.5563.146',\n          chrome: {\n            chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n            userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.91vxAl'\n          },\n          'goog:chromeOptions': {\n            debuggerAddress: 'localhost:52839'\n          },\n          networkConnectionEnabled: false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac os x',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify',\n          'webauthn:extension:credBlob': true,\n          'webauthn:extension:largeBlob': true,\n          'webauthn:extension:minPinLength': true,\n          'webauthn:extension:prf': true,\n          'webauthn:virtualAuthenticators': true\n        },\n        sessionId: '9a61f4d0e9b27287c69a1932a5ce9f29',\n        projectName: '',\n        buildName: '',\n        testEnv: 'chrome',\n        isMobile: false,\n        status: 'fail',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/duckDuckGo_chromedriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 1,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:18:29.971Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:31.594Z',\n            '  Response 200 POST /session (1624ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.91vxAl&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:52839&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;9a61f4d0e9b27287c69a1932a5ce9f29&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:31.604Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://duckduckgo.com&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:35.227Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/url (3624ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:35.251Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:35.282Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (33ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:35.785Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:35.789Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:36.292Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.297Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:36.800Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:36.804Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:37.305Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.309Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:37.812Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.818Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (7ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.321Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.326Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.828Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.833Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.335Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:39.339Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.839Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:39.844Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.346Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.350Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.410Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/9a61f4d0e9b27287c69a1932a5ce9f29/screenshot  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.526Z',\n            '  Response 200 GET /session/9a61f4d0e9b27287c69a1932a5ce9f29/screenshot (110ms)',\n            '{\\n     value: <span style=\"color:#0A0\">&#39;iVBORw0KGgoAAAANSUhEUgAABLAAAAN3CAYAAAAia6NNAAABKGlDQ1BTa2lhAAAokX2QPUvDUBSGH0sX0aGiooNDNruo/bDVQpcm...&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.535Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/9a61f4d0e9b27287c69a1932a5ce9f29  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.596Z',\n            '  Response 200 DELETE /session/9a61f4d0e9b27287c69a1932a5ce9f29 (60ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:18:29.971Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:31.594Z',\n            '  Response 200 POST /session (1624ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.91vxAl\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:52839\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'9a61f4d0e9b27287c69a1932a5ce9f29\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:31.604Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/url  ',\n            '{ url: \\'https://duckduckgo.com\\' }'\n          ],\n          [\n            '2023-04-06T10:18:35.227Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/url (3624ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:35.251Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:35.282Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (33ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:35.785Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:35.789Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:36.292Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.297Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:36.800Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:36.804Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:37.305Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.309Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:37.812Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.818Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (7ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.321Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:38.326Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.828Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:38.833Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.335Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:39.339Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.839Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:39.844Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.346Z',\n            '  Request POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:18:40.350Z',\n            '  Response 200 POST /session/9a61f4d0e9b27287c69a1932a5ce9f29/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.410Z',\n            '  Request GET /session/9a61f4d0e9b27287c69a1932a5ce9f29/screenshot  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:40.526Z',\n            '  Response 200 GET /session/9a61f4d0e9b27287c69a1932a5ce9f29/screenshot (110ms)',\n            '{\\n     value: \\'iVBORw0KGgoAAAANSUhEUgAABLAAAAN3CAYAAAAia6NNAAABKGlDQ1BTa2lhAAAokX2QPUvDUBSGH0sX0aGiooNDNruo/bDVQpcm...\\',\\n     suppressBase64Data: true\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:40.535Z',\n            '  Request DELETE /session/9a61f4d0e9b27287c69a1932a5ce9f29  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:40.596Z',\n            '  Response 200 DELETE /session/9a61f4d0e9b27287c69a1932a5ce9f29 (60ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      googlePageObject: {\n        reportPrefix: 'CHROME_111.0.5563.146__',\n        assertionsCount: 0,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '5.086',\n        timeMs: 5086,\n        completed: {\n          'should complete the consent form': {\n            time: '5.086',\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'should complete the consent form': {\n                time: '5.086',\n                assertions: [\n                ],\n                tests: 0,\n                commands: [\n                ],\n                passed: 0,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 5086,\n                startTimestamp: 'Thu, 06 Apr 2023 10:18:37 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:18:42 GMT'\n              }\n            },\n            timeMs: 5086,\n            startTimestamp: 'Thu, 06 Apr 2023 10:18:37 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:18:42 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'url',\n                args: [\n                  'https://google.no',\n                  null\n                ],\n                startTime: 1680776313471,\n                endTime: 1680776317554,\n                elapsedTime: 4083,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'should complete the consent form': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'isPresent',\n                args: [\n                  'Element [name=@consentModal]'\n                ],\n                startTime: 1680776317560,\n                endTime: 1680776322642,\n                elapsedTime: 5082,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'quit',\n                args: [\n                ],\n                startTime: 1680776322643,\n                endTime: 1680776322701,\n                elapsedTime: 58,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 0,\n        group: '',\n        modulePath: '/examples/tests/googlePageObject.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:18:31 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:18:42 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'chrome',\n          browserVersion: '111.0.5563.146',\n          chrome: {\n            chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n            userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.39FoXo'\n          },\n          'goog:chromeOptions': {\n            debuggerAddress: 'localhost:52882'\n          },\n          networkConnectionEnabled: false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac os x',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify',\n          'webauthn:extension:credBlob': true,\n          'webauthn:extension:largeBlob': true,\n          'webauthn:extension:minPinLength': true,\n          'webauthn:extension:prf': true,\n          'webauthn:virtualAuthenticators': true\n        },\n        sessionId: '95004e1d90a7d381a02021ba1160569b',\n        projectName: '',\n        buildName: '',\n        testEnv: 'chrome',\n        isMobile: false,\n        status: 'skip',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/googlePageObject_chromedriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:18:31.838Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:33.459Z',\n            '  Response 200 POST /session (1623ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.39FoXo&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:52882&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;95004e1d90a7d381a02021ba1160569b&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:33.475Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://google.no&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.553Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/url (4079ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:37.563Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.571Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (9ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.074Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.081Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (7ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.583Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.588Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.091Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:39.096Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (6ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.598Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:39.603Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.105Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.108Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.611Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.615Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:41.117Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:41.122Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:41.624Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:41.628Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.130Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.134Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.635Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/95004e1d90a7d381a02021ba1160569b/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.640Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.644Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/95004e1d90a7d381a02021ba1160569b  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.700Z',\n            '  Response 200 DELETE /session/95004e1d90a7d381a02021ba1160569b (56ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:18:31.838Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:33.459Z',\n            '  Response 200 POST /session (1623ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.39FoXo\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:52882\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'95004e1d90a7d381a02021ba1160569b\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:33.475Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/url  ',\n            '{ url: \\'https://google.no\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.553Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/url (4079ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:37.563Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.571Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (9ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.074Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:38.081Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (7ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.583Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:38.588Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.091Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:39.096Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (6ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.598Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:39.603Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.105Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:40.108Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.611Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:40.615Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:41.117Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:41.122Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:41.624Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:41.628Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.130Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:42.134Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.635Z',\n            '  Request POST /session/95004e1d90a7d381a02021ba1160569b/elements  ',\n            '{ using: \\'css selector\\', value: \\'[aria-modal=&quot;true&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:42.640Z',\n            '  Response 200 POST /session/95004e1d90a7d381a02021ba1160569b/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.644Z',\n            '  Request DELETE /session/95004e1d90a7d381a02021ba1160569b  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:42.700Z',\n            '  Response 200 DELETE /session/95004e1d90a7d381a02021ba1160569b (56ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      google: {\n        reportPrefix: 'CHROME_111.0.5563.146__',\n        assertionsCount: 2,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '49.04',\n        timeMs: 49044,\n        completed: {\n          'demo test using expect apis': {\n            time: '49.04',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n                stackTrace: '',\n                fullMsg: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if element <#rso>:first-child> contains text \\'Nightwatch.js\\' (25ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if element \\u001b[0;33m<#rso>:first-child>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(25ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 2,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 2,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'demo test using expect apis': {\n                time: '49.04',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if element \\u001b[0;33m<#rso>:first-child>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(25ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if element \\u001b[0;33m<#rso>:first-child>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(25ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 2,\n                commands: [\n                ],\n                passed: 2,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 49044,\n                startTimestamp: 'Thu, 06 Apr 2023 10:18:32 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:22 GMT'\n              }\n            },\n            timeMs: 49044,\n            startTimestamp: 'Thu, 06 Apr 2023 10:18:32 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:22 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'demo test using expect apis': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'http://google.no'\n                ],\n                startTime: 1680776312974,\n                endTime: 1680776317572,\n                elapsedTime: 4598,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'isPresent',\n                args: [\n                  '[aria-modal=\"true\"][title=\"Before you continue to Google Search\"]'\n                ],\n                startTime: 1680776317575,\n                endTime: 1680776322707,\n                elapsedTime: 5132,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  'form[action=\"/search\"] input[type=text]'\n                ],\n                startTime: 1680776322708,\n                endTime: 1680776322723,\n                elapsedTime: 15,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'sendKeys',\n                args: [\n                  'form[action=\"/search\"] input[type=text]',\n                  'Nightwatch.js,'\n                ],\n                startTime: 1680776322723,\n                endTime: 1680776327243,\n                elapsedTime: 4520,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.textContains',\n                args: [\n                  '#rso>:first-child',\n                  'Nightwatch.js'\n                ],\n                startTime: 1680776327243,\n                endTime: 1680776327271,\n                elapsedTime: 28,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'end',\n                args: [\n                ],\n                startTime: 1680776327271,\n                endTime: 1680776327331,\n                elapsedTime: 60,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 2,\n        group: '',\n        modulePath: '/examples/tests/google.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:18:30 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:22 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'chrome',\n          browserVersion: '111.0.5563.146',\n          chrome: {\n            chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n            userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.IYBK05'\n          },\n          'goog:chromeOptions': {\n            debuggerAddress: 'localhost:52863'\n          },\n          networkConnectionEnabled: false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac os x',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify',\n          'webauthn:extension:credBlob': true,\n          'webauthn:extension:largeBlob': true,\n          'webauthn:extension:minPinLength': true,\n          'webauthn:extension:prf': true,\n          'webauthn:virtualAuthenticators': true\n        },\n        sessionId: '6d93a1410a8c1cb1a3ebd1ab9772b5bb',\n        projectName: '',\n        buildName: '',\n        testEnv: 'chrome',\n        isMobile: false,\n        status: 'pass',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:18:31.040Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:32.967Z',\n            '  Response 200 POST /session (1929ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.IYBK05&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:52863&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;6d93a1410a8c1cb1a3ebd1ab9772b5bb&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:32.976Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;http://google.no&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.570Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/url (4594ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:37.579Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.622Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (44ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.126Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.131Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (6ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.636Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.654Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (20ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.157Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:39.162Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.664Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:39.669Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.170Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.175Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.678Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.682Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:41.184Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:41.188Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:41.690Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:41.694Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.195Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.199Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.702Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.706Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.709Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;form[action=&quot;/search&quot;] input[type=text]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.714Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.716Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.722Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/execute/sync (6ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.725Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;form[action=&quot;/search&quot;] input[type=text]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.729Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:42.731Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/element/1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4/value  </span></b>',\n            '{\\n     text: <span style=\"color:#0A0\">&#39;Nightwatch.js&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;N&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;.&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;j&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:47.242Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/element/1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4/value (4512ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:47.245Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#rso&gt;:first-child&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:47.250Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;a8c9c2b4-ff04-44ee-bab0-2c0346ca5a9a&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:47.251Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/element/a8c9c2b4-ff04-44ee-bab0-2c0346ca5a9a/text  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:47.268Z',\n            '  Response 200 GET /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/element/a8c9c2b4-ff04-44ee-bab0-2c0346ca5a9a/text (17ms)',\n            '{\\n     value: <span style=\"color:#0A0\">&#39;Web result with site links\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwatch.js | Node.js powered End-to-End testing framework\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwatch....&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:47.274Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:47.330Z',\n            '  Response 200 DELETE /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb (57ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:18:31.040Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:32.967Z',\n            '  Response 200 POST /session (1929ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.IYBK05\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:52863\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'6d93a1410a8c1cb1a3ebd1ab9772b5bb\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:32.976Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/url  ',\n            '{ url: \\'http://google.no\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.570Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/url (4594ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:37.579Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:37.622Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (44ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.126Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.131Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (6ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:38.636Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.654Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (20ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.157Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:39.162Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:39.664Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:39.669Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.170Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:40.175Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:40.678Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:40.682Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:41.184Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:41.188Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:41.690Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:41.694Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.195Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:42.199Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.702Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:42.706Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:18:42.709Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'form[action=&quot;/search&quot;] input[type=text]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:42.714Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:42.716Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4\\',\\n         ELEMENT: \\'1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:42.722Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/execute/sync (6ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:18:42.725Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'form[action=&quot;/search&quot;] input[type=text]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:42.729Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:42.731Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/element/1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4/value  ',\n            '{\\n     text: \\'Nightwatch.js\\',\\n     value: [\\n       \\'N\\', \\'i\\', \\'g\\', \\'h\\',\\n       \\'t\\', \\'w\\', \\'a\\', \\'t\\',\\n       \\'c\\', \\'h\\', \\'.\\', \\'j\\',\\n       \\'s\\', \\'\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:47.242Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/element/1f8bfa3c-6bee-4e0d-9622-d75e81e8e8c4/value (4512ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:47.245Z',\n            '  Request POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements  ',\n            '{ using: \\'css selector\\', value: \\'#rso&gt;:first-child\\' }'\n          ],\n          [\n            '2023-04-06T10:18:47.250Z',\n            '  Response 200 POST /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'a8c9c2b4-ff04-44ee-bab0-2c0346ca5a9a\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:47.251Z',\n            '  Request GET /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/element/a8c9c2b4-ff04-44ee-bab0-2c0346ca5a9a/text  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:47.268Z',\n            '  Response 200 GET /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb/element/a8c9c2b4-ff04-44ee-bab0-2c0346ca5a9a/text (17ms)',\n            '{\\n     value: \\'Web result with site links\\\\n\\' +\\n       \\'\\\\n\\' +\\n       \\'Nightwatch.js | Node.js powered End-to-End testing framework\\\\n\\' +\\n       \\'Nightwatch....\\',\\n     suppressBase64Data: true\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:47.274Z',\n            '  Request DELETE /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:47.330Z',\n            '  Response 200 DELETE /session/6d93a1410a8c1cb1a3ebd1ab9772b5bb (57ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      shadowRootExample: {\n        reportPrefix: 'CHROME_111.0.5563.146__',\n        assertionsCount: 3,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '1.116',\n        timeMs: 1116,\n        completed: {\n          'retrieve the shadowRoot': {\n            time: '1.116',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Element <form> was visible after 21 milliseconds.',\n                stackTrace: '',\n                fullMsg: 'Element <form> was visible after 21 milliseconds.',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected \\'Your card validation code (CVC) is an…\\'  to be a(\\'string\\') and to include(\\'card validation code\\'): ',\n                stackTrace: '',\n                fullMsg: 'Expected \\'Your card validation code (CVC) is an…\\'  to be a(\\'string\\') and to include(\\'card validation code\\'): ',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected element <unknown selector> to be an img (5ms)',\n                stackTrace: '',\n                fullMsg: 'Expected element <unknown selector> to be an img\\u001b[0;90m (5ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 3,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 3,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'retrieve the shadowRoot': {\n                time: '1.116',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <form> was visible after 21 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <form> was visible after 21 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected \\'Your card validation code (CVC) is an…\\'  to be a(\\'string\\') and to include(\\'card validation code\\'): ',\n                    stackTrace: '',\n                    fullMsg: 'Expected \\'Your card validation code (CVC) is an…\\'  to be a(\\'string\\') and to include(\\'card validation code\\'): ',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <unknown selector> to be an img\\u001b[0;90m (5ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <unknown selector> to be an img\\u001b[0;90m (5ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 3,\n                commands: [\n                ],\n                passed: 3,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 1116,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:22 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:23 GMT'\n              }\n            },\n            timeMs: 1116,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:22 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:23 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'retrieve the shadowRoot': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://mdn.github.io/web-components-examples/popup-info-box-web-component/'\n                ],\n                startTime: 1680776362014,\n                endTime: 1680776363051,\n                elapsedTime: 1037,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  'form'\n                ],\n                startTime: 1680776363052,\n                endTime: 1680776363074,\n                elapsedTime: 22,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'getShadowRoot',\n                args: [\n                  'popup-info'\n                ],\n                startTime: 1680776363076,\n                endTime: 1680776363089,\n                elapsedTime: 13,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'element().find',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776363091,\n                endTime: 1680776363098,\n                elapsedTime: 7,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'element().property',\n                args: [\n                  'innerHTML'\n                ],\n                startTime: 1680776363101,\n                endTime: 1680776363105,\n                elapsedTime: 4,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'element().find',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776363105,\n                endTime: 1680776363113,\n                elapsedTime: 8,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'getFirstElementChild',\n                args: [\n                  'web element{3c89c9b5-8fd4-4b78-b2d7-c88f75569ffb}'\n                ],\n                startTime: 1680776363113,\n                endTime: 1680776363117,\n                elapsedTime: 4,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'expect.element',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776363121,\n                endTime: 1680776363127,\n                elapsedTime: 6,\n                status: 'pass',\n                result: {\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776363135,\n                endTime: 1680776363190,\n                elapsedTime: 55,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 3,\n        group: '',\n        modulePath: '/examples/tests/shadowRootExample.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:21 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:23 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'chrome',\n          browserVersion: '111.0.5563.146',\n          chrome: {\n            chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n            userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.Nvnx84'\n          },\n          'goog:chromeOptions': {\n            debuggerAddress: 'localhost:53167'\n          },\n          networkConnectionEnabled: false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac os x',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify',\n          'webauthn:extension:credBlob': true,\n          'webauthn:extension:largeBlob': true,\n          'webauthn:extension:minPinLength': true,\n          'webauthn:extension:prf': true,\n          'webauthn:virtualAuthenticators': true\n        },\n        sessionId: '8fa96f7ec7ee22f4ac363f003489ea0c',\n        projectName: '',\n        buildName: '',\n        testEnv: 'chrome',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/shadowRootExample_chromedriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:19:21.124Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:22.006Z',\n            '  Response 200 POST /session (883ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.Nvnx84&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:53167&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;8fa96f7ec7ee22f4ac363f003489ea0c&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:22.016Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/url  </span></b>',\n            '{\\n     url: <span style=\"color:#0A0\">&#39;https://mdn.github.io/web-components-examples/popup-info-box-web-component/&#39;<span style=\"color:#FFF\">\\n  }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.050Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/url (1035ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:23.053Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;form&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.061Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/elements (8ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;1e95cf14-4e05-4b2b-bcb7-298446591a2e&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.063Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;1e95cf14-4e05-4b2b-bcb7-298446591a2e&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;1e95cf14-4e05-4b2b-bcb7-298446591a2e&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.073Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync (11ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.077Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;popup-info&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.083Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/elements (6ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;31537dad-d980-4c26-9eb4-948c0cf328e8&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.085Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(element) {\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;            return element &amp;&amp; element.shadowRoot;\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;          }).apply(null, arguments);... (114 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;31537dad-d980-4c26-9eb4-948c0cf328e8&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.088Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync (4ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;shadow-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;067b78f3-a72a-498f-8f5e-ddb4c7024316&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.092Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/067b78f3-a72a-498f-8f5e-ddb4c7024316/element  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;.info&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.098Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/067b78f3-a72a-498f-8f5e-ddb4c7024316/element (7ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;30144c92-7c71-4e06-901e-467463c951bf&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.101Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/30144c92-7c71-4e06-901e-467463c951bf/property/innerHTML  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.104Z',\n            '  Response 200 GET /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/30144c92-7c71-4e06-901e-467463c951bf/property/innerHTML (3ms)',\n            '{\\n     value: <span style=\"color:#0A0\">&#39;Your card validation code (CVC) is an extra security feature — it is the last 3 or 4 numbers on the ...&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.106Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/067b78f3-a72a-498f-8f5e-ddb4c7024316/element  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;.icon&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.112Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/067b78f3-a72a-498f-8f5e-ddb4c7024316/element (6ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;3c89c9b5-8fd4-4b78-b2d7-c88f75569ffb&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.114Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(element) {\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;            return element &amp;&amp; element.firstElementChild;\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;          }).apply(null, arguments);... (121 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;3c89c9b5-8fd4-4b78-b2d7-c88f75569ffb&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.117Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync (3ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;377bb71f-6069-4e44-9c11-ad467daa912f&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.123Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/377bb71f-6069-4e44-9c11-ad467daa912f/name  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.125Z',\n            '  Response 200 GET /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/377bb71f-6069-4e44-9c11-ad467daa912f/name (3ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;img&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.138Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/8fa96f7ec7ee22f4ac363f003489ea0c  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:23.189Z',\n            '  Response 200 DELETE /session/8fa96f7ec7ee22f4ac363f003489ea0c (52ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:19:21.124Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:22.006Z',\n            '  Response 200 POST /session (883ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.Nvnx84\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:53167\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'8fa96f7ec7ee22f4ac363f003489ea0c\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:22.016Z',\n            '  Request POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/url  ',\n            '{\\n     url: \\'https://mdn.github.io/web-components-examples/popup-info-box-web-component/\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.050Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/url (1035ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:23.053Z',\n            '  Request POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/elements  ',\n            '{ using: \\'css selector\\', value: \\'form\\' }'\n          ],\n          [\n            '2023-04-06T10:19:23.061Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/elements (8ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'1e95cf14-4e05-4b2b-bcb7-298446591a2e\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.063Z',\n            '  Request POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'1e95cf14-4e05-4b2b-bcb7-298446591a2e\\',\\n         ELEMENT: \\'1e95cf14-4e05-4b2b-bcb7-298446591a2e\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.073Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync (11ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:19:23.077Z',\n            '  Request POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/elements  ',\n            '{ using: \\'css selector\\', value: \\'popup-info\\' }'\n          ],\n          [\n            '2023-04-06T10:19:23.083Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/elements (6ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'31537dad-d980-4c26-9eb4-948c0cf328e8\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.085Z',\n            '  Request POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync  ',\n            '{\\n     script: \\'return (function(element) {\\\\n\\' +\\n       \\'            return element &amp;&amp; element.shadowRoot;\\\\n\\' +\\n       \\'          }).apply(null, arguments);... (114 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'31537dad-d980-4c26-9eb4-948c0cf328e8\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.088Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync (4ms)',\n            '{\\n     value: {\\n       \\'shadow-6066-11e4-a52e-4f735466cecf\\': \\'067b78f3-a72a-498f-8f5e-ddb4c7024316\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.092Z',\n            '  Request POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/067b78f3-a72a-498f-8f5e-ddb4c7024316/element  ',\n            '{ using: \\'css selector\\', value: \\'.info\\' }'\n          ],\n          [\n            '2023-04-06T10:19:23.098Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/067b78f3-a72a-498f-8f5e-ddb4c7024316/element (7ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'30144c92-7c71-4e06-901e-467463c951bf\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.101Z',\n            '  Request GET /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/30144c92-7c71-4e06-901e-467463c951bf/property/innerHTML  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:23.104Z',\n            '  Response 200 GET /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/30144c92-7c71-4e06-901e-467463c951bf/property/innerHTML (3ms)',\n            '{\\n     value: \\'Your card validation code (CVC) is an extra security feature — it is the last 3 or 4 numbers on the ...\\',\\n     suppressBase64Data: true\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.106Z',\n            '  Request POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/067b78f3-a72a-498f-8f5e-ddb4c7024316/element  ',\n            '{ using: \\'css selector\\', value: \\'.icon\\' }'\n          ],\n          [\n            '2023-04-06T10:19:23.112Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/067b78f3-a72a-498f-8f5e-ddb4c7024316/element (6ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'3c89c9b5-8fd4-4b78-b2d7-c88f75569ffb\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.114Z',\n            '  Request POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync  ',\n            '{\\n     script: \\'return (function(element) {\\\\n\\' +\\n       \\'            return element &amp;&amp; element.firstElementChild;\\\\n\\' +\\n       \\'          }).apply(null, arguments);... (121 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'3c89c9b5-8fd4-4b78-b2d7-c88f75569ffb\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.117Z',\n            '  Response 200 POST /session/8fa96f7ec7ee22f4ac363f003489ea0c/execute/sync (3ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'377bb71f-6069-4e44-9c11-ad467daa912f\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:23.123Z',\n            '  Request GET /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/377bb71f-6069-4e44-9c11-ad467daa912f/name  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:23.125Z',\n            '  Response 200 GET /session/8fa96f7ec7ee22f4ac363f003489ea0c/element/377bb71f-6069-4e44-9c11-ad467daa912f/name (3ms)',\n            '{ value: \\'img\\' }'\n          ],\n          [\n            '2023-04-06T10:19:23.138Z',\n            '  Request DELETE /session/8fa96f7ec7ee22f4ac363f003489ea0c  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:23.189Z',\n            '  Response 200 DELETE /session/8fa96f7ec7ee22f4ac363f003489ea0c (52ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      vueTodoList: {\n        reportPrefix: 'CHROME_111.0.5563.146__',\n        assertionsCount: 3,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '0.8370',\n        timeMs: 837,\n        completed: {\n          'should add a todo using global element()': {\n            time: '0.8370',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected elements <#todo-list ul li> count to equal: \"5\" (9ms)',\n                stackTrace: '',\n                fullMsg: 'Expected elements <#todo-list ul li> count to equal: \\u001b[0;33m\"5\"\\u001b[0m\\u001b[0;90m (9ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected element <#todo-list ul li> text to contain: \"what is nightwatch?\" (29ms)',\n                stackTrace: '',\n                fullMsg: 'Expected element <#todo-list ul li> text to contain: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (29ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected elements <#todo-list ul li input:checked> count to equal: \"3\" (13ms)',\n                stackTrace: '',\n                fullMsg: 'Expected elements <#todo-list ul li input:checked> count to equal: \\u001b[0;33m\"3\"\\u001b[0m\\u001b[0;90m (13ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 3,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 3,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'should add a todo using global element()': {\n                time: '0.8370',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected elements <#todo-list ul li> count to equal: \\u001b[0;33m\"5\"\\u001b[0m\\u001b[0;90m (9ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected elements <#todo-list ul li> count to equal: \\u001b[0;33m\"5\"\\u001b[0m\\u001b[0;90m (9ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <#todo-list ul li> text to contain: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (29ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <#todo-list ul li> text to contain: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (29ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected elements <#todo-list ul li input:checked> count to equal: \\u001b[0;33m\"3\"\\u001b[0m\\u001b[0;90m (13ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected elements <#todo-list ul li input:checked> count to equal: \\u001b[0;33m\"3\"\\u001b[0m\\u001b[0;90m (13ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 3,\n                commands: [\n                ],\n                passed: 3,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 837,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:24 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:24 GMT'\n              }\n            },\n            timeMs: 837,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:24 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:24 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'should add a todo using global element()': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://todo-vue3-vite.netlify.app/'\n                ],\n                startTime: 1680776364046,\n                endTime: 1680776364619,\n                elapsedTime: 573,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'sendKeys',\n                args: [\n                  '#new-todo-input',\n                  'what is nightwatch?'\n                ],\n                startTime: 1680776364620,\n                endTime: 1680776364733,\n                elapsedTime: 113,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'click',\n                args: [\n                  'form button[type=\"submit\"]'\n                ],\n                startTime: 1680776364733,\n                endTime: 1680776364771,\n                elapsedTime: 38,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'expect.elements',\n                args: [\n                  '#todo-list ul li'\n                ],\n                startTime: 1680776364775,\n                endTime: 1680776364785,\n                elapsedTime: 10,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'expect.element',\n                args: [\n                  '#todo-list ul li'\n                ],\n                startTime: 1680776364785,\n                endTime: 1680776364815,\n                elapsedTime: 30,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'element().findElement',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776364815,\n                endTime: 1680776364823,\n                elapsedTime: 8,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'click',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776364823,\n                endTime: 1680776364863,\n                elapsedTime: 40,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'expect.elements',\n                args: [\n                  '#todo-list ul li input:checked'\n                ],\n                startTime: 1680776364867,\n                endTime: 1680776364881,\n                elapsedTime: 14,\n                status: 'pass',\n                result: {\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776364887,\n                endTime: 1680776364948,\n                elapsedTime: 61,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 3,\n        group: '',\n        modulePath: '/examples/tests/vueTodoList.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:23 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:24 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'chrome',\n          browserVersion: '111.0.5563.146',\n          chrome: {\n            chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n            userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.W2KVEX'\n          },\n          'goog:chromeOptions': {\n            debuggerAddress: 'localhost:53194'\n          },\n          networkConnectionEnabled: false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac os x',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify',\n          'webauthn:extension:credBlob': true,\n          'webauthn:extension:largeBlob': true,\n          'webauthn:extension:minPinLength': true,\n          'webauthn:extension:prf': true,\n          'webauthn:virtualAuthenticators': true\n        },\n        sessionId: 'f3ec74bf3829675b4d3a0431221daa4f',\n        projectName: '',\n        buildName: '',\n        testEnv: 'chrome',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/vueTodoList_chromedriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:19:23.195Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.038Z',\n            '  Response 200 POST /session (844ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.W2KVEX&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:53194&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;f3ec74bf3829675b4d3a0431221daa4f&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.048Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/f3ec74bf3829675b4d3a0431221daa4f/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://todo-vue3-vite.netlify.app/&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.618Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/url (571ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:24.621Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#new-todo-input&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.633Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements (12ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;4bac2891-cb8f-4d71-9754-9ba17acab456&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.635Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/4bac2891-cb8f-4d71-9754-9ba17acab456/value  </span></b>',\n            '{\\n     text: <span style=\"color:#0A0\">&#39;what is nightwatch?&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;n&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;?&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.732Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/4bac2891-cb8f-4d71-9754-9ba17acab456/value (97ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:24.734Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;form button[type=&quot;submit&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.741Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements (7ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;a051cb42-6696-44ea-8d6a-77c55b0440c1&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.743Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/a051cb42-6696-44ea-8d6a-77c55b0440c1/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:24.770Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/a051cb42-6696-44ea-8d6a-77c55b0440c1/click (27ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:24.776Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#todo-list ul li&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.784Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements (8ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;3f698484-5c27-4c9e-b834-5b01c93eecd6&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;2476bf09-a2f0-4475-a807-467cf541fd79&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;08f7d964-53c3-4e38-b4e8-a5f5a4b0bdd2&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;87493ead-1c61-48de-8a14-1079b940015a&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;e232016a-f7ad-4a66-8ad0-0d466a68cd9a&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.786Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#todo-list ul li&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.790Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements (4ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;3f698484-5c27-4c9e-b834-5b01c93eecd6&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;2476bf09-a2f0-4475-a807-467cf541fd79&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;08f7d964-53c3-4e38-b4e8-a5f5a4b0bdd2&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;87493ead-1c61-48de-8a14-1079b940015a&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;e232016a-f7ad-4a66-8ad0-0d466a68cd9a&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.792Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/f3ec74bf3829675b4d3a0431221daa4f/element/e232016a-f7ad-4a66-8ad0-0d466a68cd9a/text  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.814Z',\n            '  Response 200 GET /session/f3ec74bf3829675b4d3a0431221daa4f/element/e232016a-f7ad-4a66-8ad0-0d466a68cd9a/text (23ms)',\n            '{\\n     value: <span style=\"color:#0A0\">&#39;new taskwhat is nightwatch?\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Edit\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;New Taskwhat Is Nightwatch?\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Delete\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;New Taskwhat Is Nightwatch?&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.816Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/e232016a-f7ad-4a66-8ad0-0d466a68cd9a/element  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=&quot;checkbox&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.822Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/e232016a-f7ad-4a66-8ad0-0d466a68cd9a/element (6ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;7fbbfbbe-ad13-441e-a05e-fb6d3dfa7ded&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.824Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/7fbbfbbe-ad13-441e-a05e-fb6d3dfa7ded/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:24.862Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/7fbbfbbe-ad13-441e-a05e-fb6d3dfa7ded/click (38ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:24.870Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#todo-list ul li input:checked&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.880Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements (11ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9313f9c9-2ffa-4132-9e70-de03bc78981c&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;217ad052-c671-4fc9-9760-de59964629bf&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;7fbbfbbe-ad13-441e-a05e-fb6d3dfa7ded&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.892Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/f3ec74bf3829675b4d3a0431221daa4f  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:24.947Z',\n            '  Response 200 DELETE /session/f3ec74bf3829675b4d3a0431221daa4f (56ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:19:23.195Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:24.038Z',\n            '  Response 200 POST /session (844ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.W2KVEX\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:53194\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'f3ec74bf3829675b4d3a0431221daa4f\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:24.048Z',\n            '  Request POST /session/f3ec74bf3829675b4d3a0431221daa4f/url  ',\n            '{ url: \\'https://todo-vue3-vite.netlify.app/\\' }'\n          ],\n          [\n            '2023-04-06T10:19:24.618Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/url (571ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:24.621Z',\n            '  Request POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements  ',\n            '{ using: \\'css selector\\', value: \\'#new-todo-input\\' }'\n          ],\n          [\n            '2023-04-06T10:19:24.633Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements (12ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'4bac2891-cb8f-4d71-9754-9ba17acab456\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:24.635Z',\n            '  Request POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/4bac2891-cb8f-4d71-9754-9ba17acab456/value  ',\n            '{\\n     text: \\'what is nightwatch?\\',\\n     value: [\\n       \\'w\\', \\'h\\', \\'a\\', \\'t\\', \\' \\',\\n       \\'i\\', \\'s\\', \\' \\', \\'n\\', \\'i\\',\\n       \\'g\\', \\'h\\', \\'t\\', \\'w\\', \\'a\\',\\n       \\'t\\', \\'c\\', \\'h\\', \\'?\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:24.732Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/4bac2891-cb8f-4d71-9754-9ba17acab456/value (97ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:24.734Z',\n            '  Request POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements  ',\n            '{ using: \\'css selector\\', value: \\'form button[type=&quot;submit&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:24.741Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements (7ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'a051cb42-6696-44ea-8d6a-77c55b0440c1\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:24.743Z',\n            '  Request POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/a051cb42-6696-44ea-8d6a-77c55b0440c1/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:24.770Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/a051cb42-6696-44ea-8d6a-77c55b0440c1/click (27ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:24.776Z',\n            '  Request POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements  ',\n            '{ using: \\'css selector\\', value: \\'#todo-list ul li\\' }'\n          ],\n          [\n            '2023-04-06T10:19:24.784Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements (8ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'3f698484-5c27-4c9e-b834-5b01c93eecd6\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'2476bf09-a2f0-4475-a807-467cf541fd79\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'08f7d964-53c3-4e38-b4e8-a5f5a4b0bdd2\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'87493ead-1c61-48de-8a14-1079b940015a\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'e232016a-f7ad-4a66-8ad0-0d466a68cd9a\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:24.786Z',\n            '  Request POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements  ',\n            '{ using: \\'css selector\\', value: \\'#todo-list ul li\\' }'\n          ],\n          [\n            '2023-04-06T10:19:24.790Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements (4ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'3f698484-5c27-4c9e-b834-5b01c93eecd6\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'2476bf09-a2f0-4475-a807-467cf541fd79\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'08f7d964-53c3-4e38-b4e8-a5f5a4b0bdd2\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'87493ead-1c61-48de-8a14-1079b940015a\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'e232016a-f7ad-4a66-8ad0-0d466a68cd9a\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:24.792Z',\n            '  Request GET /session/f3ec74bf3829675b4d3a0431221daa4f/element/e232016a-f7ad-4a66-8ad0-0d466a68cd9a/text  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:24.814Z',\n            '  Response 200 GET /session/f3ec74bf3829675b4d3a0431221daa4f/element/e232016a-f7ad-4a66-8ad0-0d466a68cd9a/text (23ms)',\n            '{\\n     value: \\'new taskwhat is nightwatch?\\\\n\\' +\\n       \\'Edit\\\\n\\' +\\n       \\'New Taskwhat Is Nightwatch?\\\\n\\' +\\n       \\'Delete\\\\n\\' +\\n       \\'New Taskwhat Is Nightwatch?\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:24.816Z',\n            '  Request POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/e232016a-f7ad-4a66-8ad0-0d466a68cd9a/element  ',\n            '{ using: \\'css selector\\', value: \\'input[type=&quot;checkbox&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:24.822Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/e232016a-f7ad-4a66-8ad0-0d466a68cd9a/element (6ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'7fbbfbbe-ad13-441e-a05e-fb6d3dfa7ded\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:24.824Z',\n            '  Request POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/7fbbfbbe-ad13-441e-a05e-fb6d3dfa7ded/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:24.862Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/element/7fbbfbbe-ad13-441e-a05e-fb6d3dfa7ded/click (38ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:24.870Z',\n            '  Request POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements  ',\n            '{ using: \\'css selector\\', value: \\'#todo-list ul li input:checked\\' }'\n          ],\n          [\n            '2023-04-06T10:19:24.880Z',\n            '  Response 200 POST /session/f3ec74bf3829675b4d3a0431221daa4f/elements (11ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9313f9c9-2ffa-4132-9e70-de03bc78981c\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'217ad052-c671-4fc9-9760-de59964629bf\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'7fbbfbbe-ad13-441e-a05e-fb6d3dfa7ded\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:24.892Z',\n            '  Request DELETE /session/f3ec74bf3829675b4d3a0431221daa4f  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:24.947Z',\n            '  Response 200 DELETE /session/f3ec74bf3829675b4d3a0431221daa4f (56ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      'sample-with-relative-locators': {\n        reportPrefix: 'CHROME_111.0.5563.146__',\n        assertionsCount: 5,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '0.2180',\n        timeMs: 218,\n        completed: {\n          'locate password input': {\n            time: '0.09900',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n                stackTrace: '',\n                fullMsg: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input (29ms)',\n                stackTrace: '',\n                fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (29ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \"password\" (37ms)',\n                stackTrace: '',\n                fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (37ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 3,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 3,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'locate password input': {\n                time: '0.09900',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (29ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (29ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (37ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (37ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 3,\n                commands: [\n                ],\n                passed: 3,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 99,\n                startTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT'\n              }\n            },\n            timeMs: 99,\n            startTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT'\n          },\n          'fill in password input': {\n            time: '0.1190',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Element <form.login-form> was visible after 17 milliseconds.',\n                stackTrace: '',\n                fullMsg: 'Element <form.login-form> was visible after 17 milliseconds.',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if value of element <input[type=password]> equals \\'password\\' (11ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if value of element \\u001b[0;33m<input[type=password]>\\u001b[0m equals \\u001b[0;33m\\'password\\'\\u001b[0m \\u001b[0;90m(11ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 2,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 2,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'locate password input': {\n                time: '0.09900',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 27 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (29ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (29ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (37ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (37ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 3,\n                commands: [\n                ],\n                passed: 3,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 99,\n                startTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT'\n              },\n              'fill in password input': {\n                time: '0.1190',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <form.login-form> was visible after 17 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <form.login-form> was visible after 17 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if value of element \\u001b[0;33m<input[type=password]>\\u001b[0m equals \\u001b[0;33m\\'password\\'\\u001b[0m \\u001b[0;90m(11ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if value of element \\u001b[0;33m<input[type=password]>\\u001b[0m equals \\u001b[0;33m\\'password\\'\\u001b[0m \\u001b[0;90m(11ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 2,\n                commands: [\n                ],\n                passed: 2,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 119,\n                startTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT'\n              }\n            },\n            timeMs: 119,\n            startTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://archive.org/account/login'\n                ],\n                startTime: 1680776312360,\n                endTime: 1680776318569,\n                elapsedTime: 6209,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'locate password input': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})'\n                ],\n                startTime: 1680776318572,\n                endTime: 1680776318600,\n                elapsedTime: 28,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'expect.element',\n                args: [\n                  'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})'\n                ],\n                startTime: 1680776318601,\n                endTime: 1680776318630,\n                elapsedTime: 29,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'expect.element',\n                args: [\n                  'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})'\n                ],\n                startTime: 1680776318630,\n                endTime: 1680776318668,\n                elapsedTime: 38,\n                status: 'pass',\n                result: {\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'fill in password input': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  'form.login-form'\n                ],\n                startTime: 1680776318672,\n                endTime: 1680776318689,\n                elapsedTime: 17,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'setValue',\n                args: [\n                  'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})',\n                  'password'\n                ],\n                startTime: 1680776318689,\n                endTime: 1680776318775,\n                elapsedTime: 86,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.valueEquals',\n                args: [\n                  'input[type=password]',\n                  'password'\n                ],\n                startTime: 1680776318775,\n                endTime: 1680776318787,\n                elapsedTime: 12,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                ],\n                startTime: 1680776318790,\n                endTime: 1680776318847,\n                elapsedTime: 57,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 2,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 5,\n        group: '',\n        modulePath: '/examples/tests/sample-with-relative-locators.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:18:30 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:18:38 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'chrome',\n          browserVersion: '111.0.5563.146',\n          chrome: {\n            chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n            userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.JaFqwI'\n          },\n          'goog:chromeOptions': {\n            debuggerAddress: 'localhost:52856'\n          },\n          networkConnectionEnabled: false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac os x',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify',\n          'webauthn:extension:credBlob': true,\n          'webauthn:extension:largeBlob': true,\n          'webauthn:extension:minPinLength': true,\n          'webauthn:extension:prf': true,\n          'webauthn:virtualAuthenticators': true\n        },\n        sessionId: '00dd2b665dc8d47d951758a8df6aab16',\n        projectName: '',\n        buildName: '',\n        testEnv: 'chrome',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/sample-with-relative-locators_chromedriver.log',\n        host: 'localhost',\n        tests: 2,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:18:30.901Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:32.353Z',\n            '  Response 200 POST /session (1454ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.JaFqwI&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:52856&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;00dd2b665dc8d47d951758a8df6aab16&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:32.362Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://archive.org/account/login&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.567Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/url (6205ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:38.576Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.588Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (13ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;627a1655-8ce4-4fe9-9694-bc4027e6ce99&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;68c381f6-bdd6-4553-8fd2-f849a12688fd&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.590Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.599Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (9ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.603Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.616Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (14ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;627a1655-8ce4-4fe9-9694-bc4027e6ce99&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;68c381f6-bdd6-4553-8fd2-f849a12688fd&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.618Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/name  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.629Z',\n            '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/name (11ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.633Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.654Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (22ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;627a1655-8ce4-4fe9-9694-bc4027e6ce99&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;68c381f6-bdd6-4553-8fd2-f849a12688fd&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.656Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/attribute/type  </span></b>',\n            '<span style=\"color:#555\">undefined<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.667Z',\n            '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/attribute/type (12ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;password&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.673Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;form.login-form&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.680Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/elements (8ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;8f46bd5c-745a-47f0-a218-d476c573a5cb&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.682Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;8f46bd5c-745a-47f0-a218-d476c573a5cb&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;8f46bd5c-745a-47f0-a218-d476c573a5cb&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.689Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (7ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.691Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.697Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (6ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;627a1655-8ce4-4fe9-9694-bc4027e6ce99&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;68c381f6-bdd6-4553-8fd2-f849a12688fd&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.698Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/clear  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:38.713Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/clear (15ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:38.714Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/value  </span></b>',\n            '{\\n     text: <span style=\"color:#0A0\">&#39;password&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;p&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;o&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;r&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;d&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.774Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/value (60ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:38.778Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/00dd2b665dc8d47d951758a8df6aab16/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=password]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.783Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9cd7b93b-d84a-4076-808d-69f133084e04&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.784Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/property/value  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.786Z',\n            '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/property/value (2ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;password&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.793Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/00dd2b665dc8d47d951758a8df6aab16  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:38.846Z',\n            '  Response 200 DELETE /session/00dd2b665dc8d47d951758a8df6aab16 (53ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:18:30.901Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:32.353Z',\n            '  Response 200 POST /session (1454ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.JaFqwI\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:52856\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'00dd2b665dc8d47d951758a8df6aab16\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:32.362Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/url  ',\n            '{ url: \\'https://archive.org/account/login\\' }'\n          ],\n          [\n            '2023-04-06T10:18:38.567Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/url (6205ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:38.576Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.588Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (13ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'627a1655-8ce4-4fe9-9694-bc4027e6ce99\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'68c381f6-bdd6-4553-8fd2-f849a12688fd\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.590Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\',\\n         ELEMENT: \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.599Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (9ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:18:38.603Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.616Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (14ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'627a1655-8ce4-4fe9-9694-bc4027e6ce99\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'68c381f6-bdd6-4553-8fd2-f849a12688fd\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.618Z',\n            '  Request GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/name  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:38.629Z',\n            '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/name (11ms)',\n            '{ value: \\'input\\' }'\n          ],\n          [\n            '2023-04-06T10:18:38.633Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.654Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (22ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'627a1655-8ce4-4fe9-9694-bc4027e6ce99\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'68c381f6-bdd6-4553-8fd2-f849a12688fd\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.656Z',\n            '  Request GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/attribute/type  ',\n            'undefined'\n          ],\n          [\n            '2023-04-06T10:18:38.667Z',\n            '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/attribute/type (12ms)',\n            '{ value: \\'password\\' }'\n          ],\n          [\n            '2023-04-06T10:18:38.673Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/elements  ',\n            '{ using: \\'css selector\\', value: \\'form.login-form\\' }'\n          ],\n          [\n            '2023-04-06T10:18:38.680Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/elements (8ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'8f46bd5c-745a-47f0-a218-d476c573a5cb\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.682Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'8f46bd5c-745a-47f0-a218-d476c573a5cb\\',\\n         ELEMENT: \\'8f46bd5c-745a-47f0-a218-d476c573a5cb\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.689Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (7ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:18:38.691Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.697Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/execute/sync (6ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'627a1655-8ce4-4fe9-9694-bc4027e6ce99\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'68c381f6-bdd6-4553-8fd2-f849a12688fd\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.698Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/clear  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:38.713Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/clear (15ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:38.714Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/value  ',\n            '{\\n     text: \\'password\\',\\n     value: [\\n       \\'p\\', \\'a\\', \\'s\\',\\n       \\'s\\', \\'w\\', \\'o\\',\\n       \\'r\\', \\'d\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.774Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/value (60ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:38.778Z',\n            '  Request POST /session/00dd2b665dc8d47d951758a8df6aab16/elements  ',\n            '{ using: \\'css selector\\', value: \\'input[type=password]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:38.783Z',\n            '  Response 200 POST /session/00dd2b665dc8d47d951758a8df6aab16/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9cd7b93b-d84a-4076-808d-69f133084e04\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:38.784Z',\n            '  Request GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/property/value  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:38.786Z',\n            '  Response 200 GET /session/00dd2b665dc8d47d951758a8df6aab16/element/9cd7b93b-d84a-4076-808d-69f133084e04/property/value (2ms)',\n            '{ value: \\'password\\' }'\n          ],\n          [\n            '2023-04-06T10:18:38.793Z',\n            '  Request DELETE /session/00dd2b665dc8d47d951758a8df6aab16  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:38.846Z',\n            '  Response 200 DELETE /session/00dd2b665dc8d47d951758a8df6aab16 (53ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      ecosia: {\n        reportPrefix: 'CHROME_111.0.5563.146__',\n        assertionsCount: 5,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '3.056',\n        timeMs: 3056,\n        completed: {\n          'Demo test ecosia.org': {\n            time: '3.056',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Element <body> was visible after 39 milliseconds.',\n                stackTrace: '',\n                fullMsg: 'Element <body> was visible after 39 milliseconds.',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if the page title contains \\'Ecosia\\' (7ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if the page title contains \\u001b[0;33m\\'Ecosia\\'\\u001b[0m \\u001b[0;90m(7ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if element <input[type=search]> is visible (17ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if element \\u001b[0;33m<input[type=search]>\\u001b[0m is visible \\u001b[0;90m(17ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if element <button[type=submit]> is visible (86ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if element \\u001b[0;33m<button[type=submit]>\\u001b[0m is visible \\u001b[0;90m(86ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if element <.layout__content> contains text \\'Nightwatch.js\\' (136ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if element \\u001b[0;33m<.layout__content>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(136ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 5,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 5,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'Demo test ecosia.org': {\n                time: '3.056',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <body> was visible after 39 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <body> was visible after 39 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if the page title contains \\u001b[0;33m\\'Ecosia\\'\\u001b[0m \\u001b[0;90m(7ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if the page title contains \\u001b[0;33m\\'Ecosia\\'\\u001b[0m \\u001b[0;90m(7ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if element \\u001b[0;33m<input[type=search]>\\u001b[0m is visible \\u001b[0;90m(17ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if element \\u001b[0;33m<input[type=search]>\\u001b[0m is visible \\u001b[0;90m(17ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if element \\u001b[0;33m<button[type=submit]>\\u001b[0m is visible \\u001b[0;90m(86ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if element \\u001b[0;33m<button[type=submit]>\\u001b[0m is visible \\u001b[0;90m(86ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if element \\u001b[0;33m<.layout__content>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(136ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if element \\u001b[0;33m<.layout__content>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(136ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 5,\n                commands: [\n                ],\n                passed: 5,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 3056,\n                startTimestamp: 'Thu, 06 Apr 2023 10:18:37 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:18:40 GMT'\n              }\n            },\n            timeMs: 3056,\n            startTimestamp: 'Thu, 06 Apr 2023 10:18:37 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:18:40 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://www.ecosia.org/'\n                ],\n                startTime: 1680776313426,\n                endTime: 1680776317581,\n                elapsedTime: 4155,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'Demo test ecosia.org': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  'body'\n                ],\n                startTime: 1680776317585,\n                endTime: 1680776317625,\n                elapsedTime: 40,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.titleContains',\n                args: [\n                  'Ecosia'\n                ],\n                startTime: 1680776317626,\n                endTime: 1680776317633,\n                elapsedTime: 7,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.visible',\n                args: [\n                  'input[type=search]'\n                ],\n                startTime: 1680776317633,\n                endTime: 1680776317653,\n                elapsedTime: 20,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'setValue',\n                args: [\n                  'input[type=search]',\n                  'nightwatch'\n                ],\n                startTime: 1680776317653,\n                endTime: 1680776317770,\n                elapsedTime: 117,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.visible',\n                args: [\n                  'button[type=submit]'\n                ],\n                startTime: 1680776317770,\n                endTime: 1680776317857,\n                elapsedTime: 87,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'click',\n                args: [\n                  'button[type=submit]'\n                ],\n                startTime: 1680776317858,\n                endTime: 1680776320498,\n                elapsedTime: 2640,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.textContains',\n                args: [\n                  '.layout__content',\n                  'Nightwatch.js'\n                ],\n                startTime: 1680776320498,\n                endTime: 1680776320637,\n                elapsedTime: 139,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                ],\n                startTime: 1680776320640,\n                endTime: 1680776320701,\n                elapsedTime: 61,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 5,\n        group: '',\n        modulePath: '/examples/tests/ecosia.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:18:31 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:18:40 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'chrome',\n          browserVersion: '111.0.5563.146',\n          chrome: {\n            chromedriverVersion: '111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})',\n            userDataDir: '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.crT7I3'\n          },\n          'goog:chromeOptions': {\n            debuggerAddress: 'localhost:52878'\n          },\n          networkConnectionEnabled: false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac os x',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify',\n          'webauthn:extension:credBlob': true,\n          'webauthn:extension:largeBlob': true,\n          'webauthn:extension:minPinLength': true,\n          'webauthn:extension:prf': true,\n          'webauthn:virtualAuthenticators': true\n        },\n        sessionId: '5e487662a1e1be6f6d821f923d21af64',\n        projectName: '',\n        buildName: '',\n        testEnv: 'chrome',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/ecosia_chromedriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:18:31.743Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { w3c: <span style=\"color:#A50\">true<span style=\"color:#FFF\">, args: [] }\\n       }\\n     }\\n  }</span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:33.414Z',\n            '  Response 200 POST /session (1683ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;chrome&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.5563.146&#39;<span style=\"color:#FFF\">,\\n         chrome: {\\n           chromedriverVersion: <span style=\"color:#0A0\">&#39;111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})&#39;<span style=\"color:#FFF\">,\\n           userDataDir: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.crT7I3&#39;<span style=\"color:#FFF\">\\n         },\\n         <span style=\"color:#0A0\">&#39;goog:chromeOptions&#39;<span style=\"color:#FFF\">: { debuggerAddress: <span style=\"color:#0A0\">&#39;localhost:52878&#39;<span style=\"color:#FFF\"> },\\n         networkConnectionEnabled: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac os x&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:credBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:largeBlob&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:minPinLength&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:extension:prf&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;webauthn:virtualAuthenticators&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n       },\\n       sessionId: <span style=\"color:#0A0\">&#39;5e487662a1e1be6f6d821f923d21af64&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:33.429Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://www.ecosia.org/&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.580Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/url (4152ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:37.587Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;body&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.604Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (17ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f9443218-7896-44fc-9e32-b7d8642bade8&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.608Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f9443218-7896-44fc-9e32-b7d8642bade8&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;f9443218-7896-44fc-9e32-b7d8642bade8&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.624Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (16ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.629Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/5e487662a1e1be6f6d821f923d21af64/title  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.632Z',\n            '  Response 200 GET /session/5e487662a1e1be6f6d821f923d21af64/title (4ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;Ecosia - the search engine that plants trees&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.636Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=search]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.641Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;b51dfbe1-4af2-44cb-85dc-a229a45c3c3f&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.642Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;b51dfbe1-4af2-44cb-85dc-a229a45c3c3f&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;b51dfbe1-4af2-44cb-85dc-a229a45c3c3f&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.651Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (9ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.654Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=search]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.663Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (9ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;b51dfbe1-4af2-44cb-85dc-a229a45c3c3f&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.664Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/clear  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:37.683Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/clear (19ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:37.685Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/value  </span></b>',\n            '{\\n     text: <span style=\"color:#0A0\">&#39;nightwatch&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;n&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.769Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/value (84ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:37.774Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;button[type=submit]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.843Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (69ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;dfe9ef82-4e7e-407d-b76b-86de1443ac1b&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.847Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;dfe9ef82-4e7e-407d-b76b-86de1443ac1b&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;dfe9ef82-4e7e-407d-b76b-86de1443ac1b&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.855Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (9ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.860Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;button[type=submit]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.864Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (4ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;dfe9ef82-4e7e-407d-b76b-86de1443ac1b&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:37.865Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/element/dfe9ef82-4e7e-407d-b76b-86de1443ac1b/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:40.497Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/dfe9ef82-4e7e-407d-b76b-86de1443ac1b/click (2632ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:18:40.501Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/5e487662a1e1be6f6d821f923d21af64/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;.layout__content&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.507Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (6ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;e3557007-ed36-4c86-b27a-7c09e9317276&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.509Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/5e487662a1e1be6f6d821f923d21af64/element/e3557007-ed36-4c86-b27a-7c09e9317276/text  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.634Z',\n            '  Response 200 GET /session/5e487662a1e1be6f6d821f923d21af64/element/e3557007-ed36-4c86-b27a-7c09e9317276/text (125ms)',\n            '{\\n     value: <span style=\"color:#0A0\">&#39;Search\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;https://nightwatchjs.org\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwatch.js | Node.js powered End-to-End testing framework\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwa...&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.643Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/5e487662a1e1be6f6d821f923d21af64  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:18:40.700Z',\n            '  Response 200 DELETE /session/5e487662a1e1be6f6d821f923d21af64 (57ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:18:31.743Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: {\\n       firstMatch: [ {} ],\\n       alwaysMatch: {\\n         browserName: \\'chrome\\',\\n         \\'goog:chromeOptions\\': { w3c: true, args: [] }\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:33.414Z',\n            '  Response 200 POST /session (1683ms)',\n            '{\\n     value: {\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'chrome\\',\\n         browserVersion: \\'111.0.5563.146\\',\\n         chrome: {\\n           chromedriverVersion: \\'111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})\\',\\n           userDataDir: \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/.com.google.Chrome.crT7I3\\'\\n         },\\n         \\'goog:chromeOptions\\': { debuggerAddress: \\'localhost:52878\\' },\\n         networkConnectionEnabled: false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac os x\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\',\\n         \\'webauthn:extension:credBlob\\': true,\\n         \\'webauthn:extension:largeBlob\\': true,\\n         \\'webauthn:extension:minPinLength\\': true,\\n         \\'webauthn:extension:prf\\': true,\\n         \\'webauthn:virtualAuthenticators\\': true\\n       },\\n       sessionId: \\'5e487662a1e1be6f6d821f923d21af64\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:33.429Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/url  ',\n            '{ url: \\'https://www.ecosia.org/\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.580Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/url (4152ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:37.587Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n            '{ using: \\'css selector\\', value: \\'body\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.604Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (17ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f9443218-7896-44fc-9e32-b7d8642bade8\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:37.608Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f9443218-7896-44fc-9e32-b7d8642bade8\\',\\n         ELEMENT: \\'f9443218-7896-44fc-9e32-b7d8642bade8\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:37.624Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (16ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:18:37.629Z',\n            '  Request GET /session/5e487662a1e1be6f6d821f923d21af64/title  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:37.632Z',\n            '  Response 200 GET /session/5e487662a1e1be6f6d821f923d21af64/title (4ms)',\n            '{ value: \\'Ecosia - the search engine that plants trees\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.636Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n            '{ using: \\'css selector\\', value: \\'input[type=search]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.641Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'b51dfbe1-4af2-44cb-85dc-a229a45c3c3f\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:37.642Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'b51dfbe1-4af2-44cb-85dc-a229a45c3c3f\\',\\n         ELEMENT: \\'b51dfbe1-4af2-44cb-85dc-a229a45c3c3f\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:37.651Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (9ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:18:37.654Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n            '{ using: \\'css selector\\', value: \\'input[type=search]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.663Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (9ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'b51dfbe1-4af2-44cb-85dc-a229a45c3c3f\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:37.664Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/clear  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:37.683Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/clear (19ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:37.685Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/value  ',\n            '{\\n     text: \\'nightwatch\\',\\n     value: [\\n       \\'n\\', \\'i\\', \\'g\\', \\'h\\',\\n       \\'t\\', \\'w\\', \\'a\\', \\'t\\',\\n       \\'c\\', \\'h\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:37.769Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/b51dfbe1-4af2-44cb-85dc-a229a45c3c3f/value (84ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:37.774Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n            '{ using: \\'css selector\\', value: \\'button[type=submit]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.843Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (69ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'dfe9ef82-4e7e-407d-b76b-86de1443ac1b\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:37.847Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'dfe9ef82-4e7e-407d-b76b-86de1443ac1b\\',\\n         ELEMENT: \\'dfe9ef82-4e7e-407d-b76b-86de1443ac1b\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:37.855Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/execute/sync (9ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:18:37.860Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n            '{ using: \\'css selector\\', value: \\'button[type=submit]\\' }'\n          ],\n          [\n            '2023-04-06T10:18:37.864Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (4ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'dfe9ef82-4e7e-407d-b76b-86de1443ac1b\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:37.865Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/element/dfe9ef82-4e7e-407d-b76b-86de1443ac1b/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:18:40.497Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/element/dfe9ef82-4e7e-407d-b76b-86de1443ac1b/click (2632ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:18:40.501Z',\n            '  Request POST /session/5e487662a1e1be6f6d821f923d21af64/elements  ',\n            '{ using: \\'css selector\\', value: \\'.layout__content\\' }'\n          ],\n          [\n            '2023-04-06T10:18:40.507Z',\n            '  Response 200 POST /session/5e487662a1e1be6f6d821f923d21af64/elements (6ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'e3557007-ed36-4c86-b27a-7c09e9317276\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:40.509Z',\n            '  Request GET /session/5e487662a1e1be6f6d821f923d21af64/element/e3557007-ed36-4c86-b27a-7c09e9317276/text  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:40.634Z',\n            '  Response 200 GET /session/5e487662a1e1be6f6d821f923d21af64/element/e3557007-ed36-4c86-b27a-7c09e9317276/text (125ms)',\n            '{\\n     value: \\'Search\\\\n\\' +\\n       \\'https://nightwatchjs.org\\\\n\\' +\\n       \\'Nightwatch.js | Node.js powered End-to-End testing framework\\\\n\\' +\\n       \\'Nightwa...\\',\\n     suppressBase64Data: true\\n  }'\n          ],\n          [\n            '2023-04-06T10:18:40.643Z',\n            '  Request DELETE /session/5e487662a1e1be6f6d821f923d21af64  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:18:40.700Z',\n            '  Response 200 DELETE /session/5e487662a1e1be6f6d821f923d21af64 (57ms)',\n            '{ value: null }'\n          ]\n        ]\n      }\n    },\n    firefox: {\n      angularTodoTest: {\n        reportPrefix: 'FIREFOX_111.0.1__',\n        assertionsCount: 2,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '1.908',\n        timeMs: 1908,\n        completed: {\n          'should add a todo using custom commands': {\n            time: '1.908',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected element <web element{f201c631-099d-4556-b725-1b9036ff21e7}> text to equal: \"what is nightwatch?\" (15ms)',\n                stackTrace: '',\n                fullMsg: 'Expected element <web element{f201c631-099d-4556-b725-1b9036ff21e7}> text to equal: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \"2\" (5ms)',\n                stackTrace: '',\n                fullMsg: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \\u001b[0;33m\"2\"\\u001b[0m\\u001b[0;90m (5ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 2,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 2,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'should add a todo using custom commands': {\n                time: '1.908',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <web element{f201c631-099d-4556-b725-1b9036ff21e7}> text to equal: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <web element{f201c631-099d-4556-b725-1b9036ff21e7}> text to equal: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \\u001b[0;33m\"2\"\\u001b[0m\\u001b[0;90m (5ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected elements <*[module=todoApp] li .done-true> count to equal: \\u001b[0;33m\"2\"\\u001b[0m\\u001b[0;90m (5ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 2,\n                commands: [\n                ],\n                passed: 2,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 1908,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:27 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:29 GMT'\n              }\n            },\n            timeMs: 1908,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:27 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:29 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'should add a todo using custom commands': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://angularjs.org'\n                ],\n                startTime: 1680776367982,\n                endTime: 1680776369381,\n                elapsedTime: 1399,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'sendKeys',\n                args: [\n                  '[ng-model=\"todoList.todoText\"]',\n                  'what is nightwatch?'\n                ],\n                startTime: 1680776369382,\n                endTime: 1680776369412,\n                elapsedTime: 30,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'click',\n                args: [\n                  '[value=\"add\"]'\n                ],\n                startTime: 1680776369412,\n                endTime: 1680776369631,\n                elapsedTime: 219,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'getElementsInList',\n                args: [\n                  'todoList.todos'\n                ],\n                startTime: 1680776369631,\n                endTime: 1680776369638,\n                elapsedTime: 7,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'expect.element',\n                args: [\n                  'web element{f201c631-099d-4556-b725-1b9036ff21e7}'\n                ],\n                startTime: 1680776369642,\n                endTime: 1680776369658,\n                elapsedTime: 16,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'element().findElement',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776369658,\n                endTime: 1680776369662,\n                elapsedTime: 4,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'click',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776369662,\n                endTime: 1680776369876,\n                elapsedTime: 214,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'expect.elements',\n                args: [\n                  '*[module=todoApp] li .done-true'\n                ],\n                startTime: 1680776369878,\n                endTime: 1680776369883,\n                elapsedTime: 5,\n                status: 'pass',\n                result: {\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776369890,\n                endTime: 1680776370259,\n                elapsedTime: 369,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 2,\n        group: '',\n        modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/angularTodoTest.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:25 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:29 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'firefox',\n          browserVersion: '111.0.1',\n          'moz:accessibilityChecks': false,\n          'moz:buildID': '20230321111920',\n          'moz:geckodriverVersion': '0.32.0',\n          'moz:headless': false,\n          'moz:platformVersion': '22.3.0',\n          'moz:processID': 93705,\n          'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileCfAJtT',\n          'moz:shutdownTimeout': 60000,\n          'moz:useNonSpecCompliantPointerOrigin': false,\n          'moz:webdriverClick': true,\n          'moz:windowless': false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify'\n        },\n        sessionId: '1a5fbc5c-7381-4c6e-991b-936453257b8d',\n        projectName: '',\n        buildName: '',\n        testEnv: 'firefox',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/angularTodoTest_geckodriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:19:25.817Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:27.970Z',\n            '  Response 200 POST /session (2155ms)',\n            '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;1a5fbc5c-7381-4c6e-991b-936453257b8d&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93705<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileCfAJtT&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:27.986Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://angularjs.org&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.380Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/url (1394ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:29.385Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[ng-model=&quot;todoList.todoText&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.391Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (7ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9e5ff74b-5b5b-4221-90b6-d14dcc856ec8&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.393Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/9e5ff74b-5b5b-4221-90b6-d14dcc856ec8/value  </span></b>',\n            '{\\n     text: <span style=\"color:#0A0\">&#39;what is nightwatch?&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;n&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;?&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.411Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/9e5ff74b-5b5b-4221-90b6-d14dcc856ec8/value (18ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:29.413Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;[value=&quot;add&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.416Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (3ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;b00c28b3-319c-44f5-906d-c24b3debafd7&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.418Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/b00c28b3-319c-44f5-906d-c24b3debafd7/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:29.631Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/b00c28b3-319c-44f5-906d-c24b3debafd7/click (213ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:29.634Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;var passedArgs = Array.prototype.slice.call(arguments,0); return (function(listName) {\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;      // executed in the browser context\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;      // eslint-disable-next-line\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;      var elements = document.querySel... (366 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [ <span style=\"color:#0A0\">&#39;todoList.todos&#39;<span style=\"color:#FFF\"> ]\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.637Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/execute/sync (3ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;df85178f-1166-489c-827d-17e13fecf95a&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ed6dc16b-f99b-4ab7-821b-c17030dcd5de&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f201c631-099d-4556-b725-1b9036ff21e7&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.643Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/text  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.656Z',\n            '  Response 200 GET /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/text (13ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;what is nightwatch?&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.659Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/element  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.662Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/element (3ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;8b05c802-195a-4804-a216-09892ca94a68&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.663Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/8b05c802-195a-4804-a216-09892ca94a68/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:29.875Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/8b05c802-195a-4804-a216-09892ca94a68/click (212ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:29.879Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;*[module=todoApp] li .done-true&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.883Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (4ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f027fd19-1bf0-406e-899c-c005c1e40456&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ed3f1754-6119-41a2-83c1-d56075d6b38a&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.893Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/1a5fbc5c-7381-4c6e-991b-936453257b8d  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:30.257Z',\n            '  Response 200 DELETE /session/1a5fbc5c-7381-4c6e-991b-936453257b8d (365ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:19:25.817Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:27.970Z',\n            '  Response 200 POST /session (2155ms)',\n            '{\\n     value: {\\n       sessionId: \\'1a5fbc5c-7381-4c6e-991b-936453257b8d\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93705,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileCfAJtT\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:27.986Z',\n            '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/url  ',\n            '{ url: \\'https://angularjs.org\\' }'\n          ],\n          [\n            '2023-04-06T10:19:29.380Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/url (1394ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:29.385Z',\n            '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  ',\n            '{ using: \\'css selector\\', value: \\'[ng-model=&quot;todoList.todoText&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:29.391Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (7ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9e5ff74b-5b5b-4221-90b6-d14dcc856ec8\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:29.393Z',\n            '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/9e5ff74b-5b5b-4221-90b6-d14dcc856ec8/value  ',\n            '{\\n     text: \\'what is nightwatch?\\',\\n     value: [\\n       \\'w\\', \\'h\\', \\'a\\', \\'t\\', \\' \\',\\n       \\'i\\', \\'s\\', \\' \\', \\'n\\', \\'i\\',\\n       \\'g\\', \\'h\\', \\'t\\', \\'w\\', \\'a\\',\\n       \\'t\\', \\'c\\', \\'h\\', \\'?\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:29.411Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/9e5ff74b-5b5b-4221-90b6-d14dcc856ec8/value (18ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:29.413Z',\n            '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  ',\n            '{ using: \\'css selector\\', value: \\'[value=&quot;add&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:29.416Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (3ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'b00c28b3-319c-44f5-906d-c24b3debafd7\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:29.418Z',\n            '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/b00c28b3-319c-44f5-906d-c24b3debafd7/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:29.631Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/b00c28b3-319c-44f5-906d-c24b3debafd7/click (213ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:29.634Z',\n            '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/execute/sync  ',\n            '{\\n     script: \\'var passedArgs = Array.prototype.slice.call(arguments,0); return (function(listName) {\\\\n\\' +\\n       \\'      // executed in the browser context\\\\n\\' +\\n       \\'      // eslint-disable-next-line\\\\n\\' +\\n       \\'      var elements = document.querySel... (366 characters)\\',\\n     args: [ \\'todoList.todos\\' ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:29.637Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/execute/sync (3ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'df85178f-1166-489c-827d-17e13fecf95a\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ed6dc16b-f99b-4ab7-821b-c17030dcd5de\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f201c631-099d-4556-b725-1b9036ff21e7\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:29.643Z',\n            '  Request GET /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/text  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:29.656Z',\n            '  Response 200 GET /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/text (13ms)',\n            '{ value: \\'what is nightwatch?\\' }'\n          ],\n          [\n            '2023-04-06T10:19:29.659Z',\n            '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/element  ',\n            '{ using: \\'css selector\\', value: \\'input\\' }'\n          ],\n          [\n            '2023-04-06T10:19:29.662Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/f201c631-099d-4556-b725-1b9036ff21e7/element (3ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'8b05c802-195a-4804-a216-09892ca94a68\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:29.663Z',\n            '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/8b05c802-195a-4804-a216-09892ca94a68/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:29.875Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/element/8b05c802-195a-4804-a216-09892ca94a68/click (212ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:29.879Z',\n            '  Request POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements  ',\n            '{ using: \\'css selector\\', value: \\'*[module=todoApp] li .done-true\\' }'\n          ],\n          [\n            '2023-04-06T10:19:29.883Z',\n            '  Response 200 POST /session/1a5fbc5c-7381-4c6e-991b-936453257b8d/elements (4ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f027fd19-1bf0-406e-899c-c005c1e40456\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ed3f1754-6119-41a2-83c1-d56075d6b38a\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:29.893Z',\n            '  Request DELETE /session/1a5fbc5c-7381-4c6e-991b-936453257b8d  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:30.257Z',\n            '  Response 200 DELETE /session/1a5fbc5c-7381-4c6e-991b-936453257b8d (365ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      chromeCDP_example: {\n        reportPrefix: 'FIREFOX_111.0.1__',\n        assertionsCount: 1,\n        lastError: {\n          name: 'NightwatchAssertError',\n          message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n          showDiff: false,\n          abortOnFailure: true,\n          stack: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)'\n        },\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '4.669',\n        timeMs: 4669,\n        completed: {\n          'using CDP DOM Snapshot': {\n            time: '4.669',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \"documents,strings\" but got: \"abortOnFailure\" (4ms)',\n                stackTrace: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)',\n                fullMsg: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n                failure: 'Expected \"documents,strings\" but got: \"abortOnFailure\"',\n                screenshots: [\n                  '/Users/vaibhavsingh/Dev/nightwatch/screens/chromeCDP_example/using-CDP-DOM-Snapshot_FAILED_Apr-06-2023-154931-GMT+0530.png'\n                ]\n              }\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 1,\n            skipped: 0,\n            tests: 1,\n            status: 'fail',\n            steps: [\n            ],\n            stackTrace: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)',\n            testcases: {\n              'using CDP DOM Snapshot': {\n                time: '4.669',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n                    stackTrace: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)',\n                    fullMsg: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n                    failure: 'Expected \"documents,strings\" but got: \"abortOnFailure\"',\n                    screenshots: [\n                      '/Users/vaibhavsingh/Dev/nightwatch/screens/chromeCDP_example/using-CDP-DOM-Snapshot_FAILED_Apr-06-2023-154931-GMT+0530.png'\n                    ]\n                  }\n                ],\n                tests: 1,\n                commands: [\n                ],\n                passed: 0,\n                errors: 0,\n                failed: 1,\n                skipped: 0,\n                status: 'fail',\n                steps: [\n                ],\n                stackTrace: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)',\n                lastError: {\n                  name: 'NightwatchAssertError',\n                  message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n                  showDiff: false,\n                  abortOnFailure: true,\n                  stack: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)'\n                },\n                timeMs: 4669,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:27 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:32 GMT'\n              }\n            },\n            lastError: {\n              name: 'NightwatchAssertError',\n              message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m',\n              showDiff: false,\n              abortOnFailure: true,\n              stack: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)'\n            },\n            timeMs: 4669,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:27 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:32 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'using CDP DOM Snapshot': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://nightwatchjs.org'\n                ],\n                startTime: 1680776367423,\n                endTime: 1680776371918,\n                elapsedTime: 4495,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'chrome.sendAndGetDevToolsCommand',\n                args: [\n                  'DOMSnapshot.captureSnapshot',\n                  '[object Object]'\n                ],\n                startTime: 1680776371920,\n                endTime: 1680776371920,\n                elapsedTime: 0,\n                status: 'fail',\n                result: {\n                  message: 'Error while running \"chrome.sendAndGetDevToolsCommand\" command: [TypeError] nightwatchInstance.transport.driver[commandName] is not a function',\n                  name: 'TypeError',\n                  abortOnFailure: true,\n                  stack: 'TypeError: Error while running \"chrome.sendAndGetDevToolsCommand\" command: [TypeError] nightwatchInstance.transport.driver[commandName] is not a function\\n    at ChromeCommandLoader.commandFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/_base-loader.js:38:62)\\n    at TreeNode.invokeCommand (/Users/vaibhavsingh/Dev/nightwatch/lib/core/treenode.js:154:31)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/core/treenode.js:177:12\\n    at new Promise (<anonymous>)\\n    at TreeNode.execute (/Users/vaibhavsingh/Dev/nightwatch/lib/core/treenode.js:176:12)\\n    at TreeNode.runCommand (/Users/vaibhavsingh/Dev/nightwatch/lib/core/treenode.js:138:27)\\n    at TreeNode.run (/Users/vaibhavsingh/Dev/nightwatch/lib/core/treenode.js:112:17)\\n    at AsyncTree.runChildNode (/Users/vaibhavsingh/Dev/nightwatch/lib/core/asynctree.js:118:31)\\n    at AsyncTree.traverse (/Users/vaibhavsingh/Dev/nightwatch/lib/core/asynctree.js:48:33)\\n    at CommandQueue.traverse (/Users/vaibhavsingh/Dev/nightwatch/lib/core/queue.js:97:8)',\n                  beautifiedStack: {\n                    filePath: '/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/_base-loader.js',\n                    error_line_number: 38,\n                    codeSnippet: [\n                      {\n                        line_number: 36,\n                        code: '  static createDriverCommand(nightwatchInstance, commandName) {'\n                      },\n                      {\n                        line_number: 37,\n                        code: '    return function commandFn({args}) {'\n                      },\n                      {\n                        line_number: 38,\n                        code: '      return nightwatchInstance.transport.driver[commandName](...args).catch((error) => {'\n                      },\n                      {\n                        line_number: 39,\n                        code: '        if (error.remoteStacktrace) {'\n                      },\n                      {\n                        line_number: 40,\n                        code: '          delete error.remoteStacktrace;'\n                      }\n                    ]\n                  }\n                }\n              },\n              {\n                name: 'assert.deepStrictEqual',\n                args: [\n                ],\n                startTime: 1680776371927,\n                endTime: 1680776371930,\n                elapsedTime: 3,\n                status: 'fail',\n                result: {\n                  message: 'Failed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \"documents,strings\" but got: \"abortOnFailure\" (4ms)',\n                  showDiff: false,\n                  name: 'NightwatchAssertError',\n                  abortOnFailure: true,\n                  stack: '+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]\\n    at Assertion.assert (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:112:34)\\n    at StaticAssert.assertFn (/Users/vaibhavsingh/Dev/nightwatch/lib/api/_loaders/static.js:146:17)\\n    at Proxy.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/lib/api/index.js:157:30)\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:10:20)',\n                  beautifiedStack: {\n                    filePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js',\n                    error_line_number: 10,\n                    codeSnippet: [\n                      {\n                        line_number: 8,\n                        code: '    });'\n                      },\n                      {\n                        line_number: 9,\n                        code: ''\n                      },\n                      {\n                        line_number: 10,\n                        code: '    browser.assert.deepStrictEqual(Object.keys(dom), [\\'documents\\', \\'strings\\']);'\n                      },\n                      {\n                        line_number: 11,\n                        code: '  });'\n                      },\n                      {\n                        line_number: 12,\n                        code: '});'\n                      }\n                    ]\n                  }\n                },\n                screenshot: '/Users/vaibhavsingh/Dev/nightwatch/screens/chromeCDP_example/using-CDP-DOM-Snapshot_FAILED_Apr-06-2023-154931-GMT+0530.png'\n              },\n              {\n                name: 'saveScreenshot',\n                args: [\n                  '/Users/vaibhavsingh/Dev/nightwatch/screens/chromeCDP_example/using-CDP-DOM-Snapshot_FAILED_Apr-06-2023-154931-GMT+0530.png',\n                  'function () { [native code] }'\n                ],\n                startTime: 1680776371985,\n                endTime: 1680776372089,\n                elapsedTime: 104,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'fail'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776372096,\n                endTime: 1680776372556,\n                elapsedTime: 460,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 1,\n        errorsCount: 0,\n        passedCount: 0,\n        group: '',\n        modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:25 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:32 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'firefox',\n          browserVersion: '111.0.1',\n          'moz:accessibilityChecks': false,\n          'moz:buildID': '20230321111920',\n          'moz:geckodriverVersion': '0.32.0',\n          'moz:headless': false,\n          'moz:platformVersion': '22.3.0',\n          'moz:processID': 93704,\n          'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofiletwZmUW',\n          'moz:shutdownTimeout': 60000,\n          'moz:useNonSpecCompliantPointerOrigin': false,\n          'moz:webdriverClick': true,\n          'moz:windowless': false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify'\n        },\n        sessionId: '245b46ac-127c-49fa-8360-05e674967894',\n        projectName: '',\n        buildName: '',\n        testEnv: 'firefox',\n        isMobile: false,\n        status: 'fail',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/chromeCDP_example_geckodriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 1,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:19:25.786Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:27.415Z',\n            '  Response 200 POST /session (1630ms)',\n            '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;245b46ac-127c-49fa-8360-05e674967894&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93704<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofiletwZmUW&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:27.426Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/245b46ac-127c-49fa-8360-05e674967894/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://nightwatchjs.org&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:31.915Z',\n            '  Response 200 POST /session/245b46ac-127c-49fa-8360-05e674967894/url (4490ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:31.987Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/245b46ac-127c-49fa-8360-05e674967894/screenshot  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:32.085Z',\n            '  Response 200 GET /session/245b46ac-127c-49fa-8360-05e674967894/screenshot (76ms)',\n            '{\\n     value: <span style=\"color:#0A0\">&#39;iVBORw0KGgoAAAANSUhEUgAACgAAAAV8CAYAAAD3/MaLAAAgAElEQVR4XuydB3wURRvG34QUQu8gXQRpoqIiVhQUBQSxgYgF+RRB...&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:32.100Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/245b46ac-127c-49fa-8360-05e674967894  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:32.554Z',\n            '  Response 200 DELETE /session/245b46ac-127c-49fa-8360-05e674967894 (454ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:19:25.786Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:27.415Z',\n            '  Response 200 POST /session (1630ms)',\n            '{\\n     value: {\\n       sessionId: \\'245b46ac-127c-49fa-8360-05e674967894\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93704,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofiletwZmUW\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:27.426Z',\n            '  Request POST /session/245b46ac-127c-49fa-8360-05e674967894/url  ',\n            '{ url: \\'https://nightwatchjs.org\\' }'\n          ],\n          [\n            '2023-04-06T10:19:31.915Z',\n            '  Response 200 POST /session/245b46ac-127c-49fa-8360-05e674967894/url (4490ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:31.987Z',\n            '  Request GET /session/245b46ac-127c-49fa-8360-05e674967894/screenshot  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:32.085Z',\n            '  Response 200 GET /session/245b46ac-127c-49fa-8360-05e674967894/screenshot (76ms)',\n            '{\\n     value: \\'iVBORw0KGgoAAAANSUhEUgAACgAAAAV8CAYAAAD3/MaLAAAgAElEQVR4XuydB3wURRvG34QUQu8gXQRpoqIiVhQUBQSxgYgF+RRB...\\',\\n     suppressBase64Data: true\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:32.100Z',\n            '  Request DELETE /session/245b46ac-127c-49fa-8360-05e674967894  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:32.554Z',\n            '  Response 200 DELETE /session/245b46ac-127c-49fa-8360-05e674967894 (454ms)',\n            '{ value: null }'\n          ]\n        ],\n        globalErrorRegister: [\n          '   \\u001b[1;31m→ ✖ \\u001b[1;31mNightwatchAssertError\\u001b[0m\\n   \\u001b[0;31mFailed [deepStrictEqual]: (Expected values to be strictly deep-equal:\\n+ actual - expected\\n\\n  [\\n+   \\'abortOnFailure\\'\\n-   \\'documents\\',\\n-   \\'strings\\'\\n  ]) - expected \\u001b[0;32m\"documents,strings\"\\u001b[0m but got: \\u001b[0;31m\"abortOnFailure\"\\u001b[0m \\u001b[0;90m(4ms)\\u001b[0m\\u001b[0m\\n\\u001b[0;33m\\n    Error location:\\u001b[0m\\n    /Users/vaibhavsingh/Dev/nightwatch/examples/tests/chromeCDP_example.js:\\n    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––\\n     8 |     });\\n     9 | \\n    \\u001b[0;37m\\u001b[41m 10 |     browser.assert.deepStrictEqual(Object.keys(dom), [\\'documents\\', \\'strings\\']); \\u001b[0m\\n     11 |   });\\n     12 | });\\n    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––\\n\\u001b[0m'\n        ]\n      },\n      duckDuckGo: {\n        reportPrefix: 'FIREFOX_111.0.1__',\n        assertionsCount: 1,\n        lastError: {\n          name: 'NightwatchAssertError',\n          message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n          showDiff: false,\n          abortOnFailure: true,\n          waitFor: true,\n          stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)'\n        },\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '5.777',\n        timeMs: 5777,\n        completed: {\n          'Search Nightwatch.js and check results': {\n            time: '5.777',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \"visible\" but got: \"not found\" (5088ms)',\n                stackTrace: '    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n                fullMsg: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n                failure: 'Expected \"visible\" but got: \"not found\"',\n                screenshots: [\n                  '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154934-GMT+0530.png'\n                ]\n              }\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 1,\n            skipped: 0,\n            tests: 1,\n            status: 'fail',\n            steps: [\n            ],\n            stackTrace: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n            testcases: {\n              'Search Nightwatch.js and check results': {\n                time: '5.777',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n                    stackTrace: '    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n                    fullMsg: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n                    failure: 'Expected \"visible\" but got: \"not found\"',\n                    screenshots: [\n                      '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154934-GMT+0530.png'\n                    ]\n                  }\n                ],\n                tests: 1,\n                commands: [\n                ],\n                passed: 0,\n                errors: 0,\n                failed: 1,\n                skipped: 0,\n                status: 'fail',\n                steps: [\n                ],\n                stackTrace: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n                lastError: {\n                  name: 'NightwatchAssertError',\n                  message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n                  showDiff: false,\n                  abortOnFailure: true,\n                  waitFor: true,\n                  stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)'\n                },\n                timeMs: 5777,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:29 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:34 GMT'\n              }\n            },\n            lastError: {\n              name: 'NightwatchAssertError',\n              message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n              showDiff: false,\n              abortOnFailure: true,\n              waitFor: true,\n              stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)'\n            },\n            timeMs: 5777,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:29 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:34 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'Search Nightwatch.js and check results': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://duckduckgo.com'\n                ],\n                startTime: 1680776369008,\n                endTime: 1680776369560,\n                elapsedTime: 552,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  '#search_form_input_homepage'\n                ],\n                startTime: 1680776369561,\n                endTime: 1680776374652,\n                elapsedTime: 5091,\n                status: 'fail',\n                result: {\n                  message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \"visible\" but got: \"not found\" (5088ms)',\n                  showDiff: false,\n                  name: 'NightwatchAssertError',\n                  abortOnFailure: true,\n                  stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)',\n                  beautifiedStack: {\n                    filePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js',\n                    error_line_number: 8,\n                    codeSnippet: [\n                      {\n                        line_number: 6,\n                        code: '    browser'\n                      },\n                      {\n                        line_number: 7,\n                        code: '      .navigateTo(\\'https://duckduckgo.com\\')'\n                      },\n                      {\n                        line_number: 8,\n                        code: '      .waitForElementVisible(\\'#search_form_input_homepage\\')'\n                      },\n                      {\n                        line_number: 9,\n                        code: '      .sendKeys(\\'#search_form_input_homepage\\', [\\'Nightwatch.js\\'])'\n                      },\n                      {\n                        line_number: 10,\n                        code: '      .click(\\'#search_button_homepage\\')'\n                      }\n                    ]\n                  }\n                },\n                screenshot: '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154934-GMT+0530.png'\n              },\n              {\n                name: 'saveScreenshot',\n                args: [\n                  '/Users/vaibhavsingh/Dev/nightwatch/screens/duckDuckGo/Search-Nightwatch.js-and-check-results_FAILED_Apr-06-2023-154934-GMT+0530.png',\n                  'function () { [native code] }'\n                ],\n                startTime: 1680776374705,\n                endTime: 1680776374779,\n                elapsedTime: 74,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'fail'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776374783,\n                endTime: 1680776375248,\n                elapsedTime: 465,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 1,\n        errorsCount: 0,\n        passedCount: 0,\n        group: '',\n        modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:26 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:34 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'firefox',\n          browserVersion: '111.0.1',\n          'moz:accessibilityChecks': false,\n          'moz:buildID': '20230321111920',\n          'moz:geckodriverVersion': '0.32.0',\n          'moz:headless': false,\n          'moz:platformVersion': '22.3.0',\n          'moz:processID': 93718,\n          'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile7QoCZB',\n          'moz:shutdownTimeout': 60000,\n          'moz:useNonSpecCompliantPointerOrigin': false,\n          'moz:webdriverClick': true,\n          'moz:windowless': false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify'\n        },\n        sessionId: '57729330-9108-4abf-9b31-a590c5cdf0e9',\n        projectName: '',\n        buildName: '',\n        testEnv: 'firefox',\n        isMobile: false,\n        status: 'fail',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/duckDuckGo_geckodriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 1,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:19:27.321Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:28.997Z',\n            '  Response 200 POST /session (1678ms)',\n            '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;57729330-9108-4abf-9b31-a590c5cdf0e9&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93718<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile7QoCZB&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.011Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://duckduckgo.com&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.559Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/url (549ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:29.563Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:29.573Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (10ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:30.075Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:30.077Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (2ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:30.581Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:30.599Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (18ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:31.101Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:31.106Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:31.608Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:31.611Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:32.115Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:32.120Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (6ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:32.622Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:32.625Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:33.128Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:33.132Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:33.635Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:33.638Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:34.140Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:34.144Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:34.646Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#search_form_input_homepage&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:34.649Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:34.708Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/57729330-9108-4abf-9b31-a590c5cdf0e9/screenshot  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:34.774Z',\n            '  Response 200 GET /session/57729330-9108-4abf-9b31-a590c5cdf0e9/screenshot (54ms)',\n            '{\\n     value: <span style=\"color:#0A0\">&#39;iVBORw0KGgoAAAANSUhEUgAACgAAAAV8CAYAAAD3/MaLAAAgAElEQVR4XuzdeZhcZZk34Kf39JLuzr5CCIQlIARZBJTFBRVRRNEZ...&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:34.787Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/57729330-9108-4abf-9b31-a590c5cdf0e9  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.245Z',\n            '  Response 200 DELETE /session/57729330-9108-4abf-9b31-a590c5cdf0e9 (456ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:19:27.321Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:28.997Z',\n            '  Response 200 POST /session (1678ms)',\n            '{\\n     value: {\\n       sessionId: \\'57729330-9108-4abf-9b31-a590c5cdf0e9\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93718,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile7QoCZB\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:29.011Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/url  ',\n            '{ url: \\'https://duckduckgo.com\\' }'\n          ],\n          [\n            '2023-04-06T10:19:29.559Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/url (549ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:29.563Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:29.573Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (10ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:30.075Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:30.077Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (2ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:30.581Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:30.599Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (18ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:31.101Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:31.106Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (5ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:31.608Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:31.611Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:32.115Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:32.120Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (6ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:32.622Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:32.625Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:33.128Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:33.132Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:33.635Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:33.638Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:34.140Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:34.144Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:34.646Z',\n            '  Request POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements  ',\n            '{ using: \\'css selector\\', value: \\'#search_form_input_homepage\\' }'\n          ],\n          [\n            '2023-04-06T10:19:34.649Z',\n            '  Response 200 POST /session/57729330-9108-4abf-9b31-a590c5cdf0e9/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:34.708Z',\n            '  Request GET /session/57729330-9108-4abf-9b31-a590c5cdf0e9/screenshot  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:34.774Z',\n            '  Response 200 GET /session/57729330-9108-4abf-9b31-a590c5cdf0e9/screenshot (54ms)',\n            '{\\n     value: \\'iVBORw0KGgoAAAANSUhEUgAACgAAAAV8CAYAAAD3/MaLAAAgAElEQVR4XuzdeZhcZZk34Kf39JLuzr5CCIQlIARZBJTFBRVRRNEZ...\\',\\n     suppressBase64Data: true\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:34.787Z',\n            '  Request DELETE /session/57729330-9108-4abf-9b31-a590c5cdf0e9  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:35.245Z',\n            '  Response 200 DELETE /session/57729330-9108-4abf-9b31-a590c5cdf0e9 (456ms)',\n            '{ value: null }'\n          ]\n        ],\n        globalErrorRegister: [\n          '   \\u001b[1;31m→ ✖ \\u001b[1;31mNightwatchAssertError\\u001b[0m\\n   \\u001b[0;31mTimed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m\\u001b[0m\\n\\u001b[0;33m\\n    Error location:\\u001b[0m\\n    /Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:\\n    –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––\\n     6 |     browser\\n     7 |       .navigateTo(\\'https://duckduckgo.com\\')\\n    \\u001b[0;37m\\u001b[41m 8 |       .waitForElementVisible(\\'#search_form_input_homepage\\') \\u001b[0m\\n     9 |       .sendKeys(\\'#search_form_input_homepage\\', [\\'Nightwatch.js\\'])\\n     10 |       .click(\\'#search_button_homepage\\')\\n    –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––\\n\\u001b[0m'\n        ]\n      },\n      googlePageObject: {\n        reportPrefix: '',\n        assertionsCount: 0,\n        lastError: null,\n        skippedAtRuntime: [\n          'should complete the consent form'\n        ],\n        skipped: [\n          'should complete the consent form'\n        ],\n        time: 0,\n        completed: {\n        },\n        completedSections: {\n        },\n        errmessages: [\n        ],\n        testsCount: 0,\n        skippedCount: 1,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 0,\n        group: '',\n        modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/googlePageObject.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:36 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:36 GMT',\n        sessionCapabilities: {\n          browserName: 'firefox',\n          alwaysMatch: {\n            acceptInsecureCerts: true,\n            'moz:firefoxOptions': {\n              args: [\n              ]\n            }\n          },\n          name: 'google search with consent form - page objects'\n        },\n        sessionId: '',\n        projectName: '',\n        buildName: '',\n        testEnv: 'firefox',\n        isMobile: false,\n        status: 'skip',\n        host: 'localhost',\n        tests: 0,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n        ],\n        rawHttpOutput: [\n        ]\n      },\n      ecosia: {\n        reportPrefix: 'FIREFOX_111.0.1__',\n        assertionsCount: 5,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '3.401',\n        timeMs: 3401,\n        completed: {\n          'Demo test ecosia.org': {\n            time: '3.401',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Element <body> was visible after 28 milliseconds.',\n                stackTrace: '',\n                fullMsg: 'Element <body> was visible after 28 milliseconds.',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if the page title contains \\'Ecosia\\' (5ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if the page title contains \\u001b[0;33m\\'Ecosia\\'\\u001b[0m \\u001b[0;90m(5ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if element <input[type=search]> is visible (42ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if element \\u001b[0;33m<input[type=search]>\\u001b[0m is visible \\u001b[0;90m(42ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if element <button[type=submit]> is visible (40ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if element \\u001b[0;33m<button[type=submit]>\\u001b[0m is visible \\u001b[0;90m(40ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if element <.layout__content> contains text \\'Nightwatch.js\\' (568ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if element \\u001b[0;33m<.layout__content>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(568ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 5,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 5,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'Demo test ecosia.org': {\n                time: '3.401',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <body> was visible after 28 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <body> was visible after 28 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if the page title contains \\u001b[0;33m\\'Ecosia\\'\\u001b[0m \\u001b[0;90m(5ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if the page title contains \\u001b[0;33m\\'Ecosia\\'\\u001b[0m \\u001b[0;90m(5ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if element \\u001b[0;33m<input[type=search]>\\u001b[0m is visible \\u001b[0;90m(42ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if element \\u001b[0;33m<input[type=search]>\\u001b[0m is visible \\u001b[0;90m(42ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if element \\u001b[0;33m<button[type=submit]>\\u001b[0m is visible \\u001b[0;90m(40ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if element \\u001b[0;33m<button[type=submit]>\\u001b[0m is visible \\u001b[0;90m(40ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if element \\u001b[0;33m<.layout__content>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(568ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if element \\u001b[0;33m<.layout__content>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(568ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 5,\n                commands: [\n                ],\n                passed: 5,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 3401,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:35 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:38 GMT'\n              }\n            },\n            timeMs: 3401,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:35 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:38 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://www.ecosia.org/'\n                ],\n                startTime: 1680776373072,\n                endTime: 1680776375295,\n                elapsedTime: 2223,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'Demo test ecosia.org': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  'body'\n                ],\n                startTime: 1680776375298,\n                endTime: 1680776375327,\n                elapsedTime: 29,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.titleContains',\n                args: [\n                  'Ecosia'\n                ],\n                startTime: 1680776375328,\n                endTime: 1680776375335,\n                elapsedTime: 7,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.visible',\n                args: [\n                  'input[type=search]'\n                ],\n                startTime: 1680776375336,\n                endTime: 1680776375378,\n                elapsedTime: 42,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'setValue',\n                args: [\n                  'input[type=search]',\n                  'nightwatch'\n                ],\n                startTime: 1680776375378,\n                endTime: 1680776375475,\n                elapsedTime: 97,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.visible',\n                args: [\n                  'button[type=submit]'\n                ],\n                startTime: 1680776375476,\n                endTime: 1680776375518,\n                elapsedTime: 42,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'click',\n                args: [\n                  'button[type=submit]'\n                ],\n                startTime: 1680776375518,\n                endTime: 1680776378119,\n                elapsedTime: 2601,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.textContains',\n                args: [\n                  '.layout__content',\n                  'Nightwatch.js'\n                ],\n                startTime: 1680776378120,\n                endTime: 1680776378695,\n                elapsedTime: 575,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                ],\n                startTime: 1680776378702,\n                endTime: 1680776379279,\n                elapsedTime: 577,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 5,\n        group: '',\n        modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/ecosia.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:31 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:38 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'firefox',\n          browserVersion: '111.0.1',\n          'moz:accessibilityChecks': false,\n          'moz:buildID': '20230321111920',\n          'moz:geckodriverVersion': '0.32.0',\n          'moz:headless': false,\n          'moz:platformVersion': '22.3.0',\n          'moz:processID': 93753,\n          'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofilekOpiU3',\n          'moz:shutdownTimeout': 60000,\n          'moz:useNonSpecCompliantPointerOrigin': false,\n          'moz:webdriverClick': true,\n          'moz:windowless': false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify'\n        },\n        sessionId: '6cb34613-0649-457f-a9db-e94b1ee7a079',\n        projectName: '',\n        buildName: '',\n        testEnv: 'firefox',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/ecosia_geckodriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:19:31.753Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:33.066Z',\n            '  Response 200 POST /session (1314ms)',\n            '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;6cb34613-0649-457f-a9db-e94b1ee7a079&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93753<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofilekOpiU3&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:33.073Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://www.ecosia.org/&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.294Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/url (2221ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:35.301Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;body&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.313Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (13ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;79fe3b43-6ef5-46f7-b81a-6ba5e43a97d0&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.315Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;79fe3b43-6ef5-46f7-b81a-6ba5e43a97d0&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;79fe3b43-6ef5-46f7-b81a-6ba5e43a97d0&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.326Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync (11ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.330Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/6cb34613-0649-457f-a9db-e94b1ee7a079/title  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.333Z',\n            '  Response 200 GET /session/6cb34613-0649-457f-a9db-e94b1ee7a079/title (3ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;Ecosia - the search engine that plants trees&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.339Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=search]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.348Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (9ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;baaff7ce-e7e4-48bf-a109-459dce9dbdfc&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.349Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;baaff7ce-e7e4-48bf-a109-459dce9dbdfc&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;baaff7ce-e7e4-48bf-a109-459dce9dbdfc&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.377Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync (28ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.379Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=search]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.385Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (6ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;baaff7ce-e7e4-48bf-a109-459dce9dbdfc&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.387Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/baaff7ce-e7e4-48bf-a109-459dce9dbdfc/clear  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:35.398Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/baaff7ce-e7e4-48bf-a109-459dce9dbdfc/clear (11ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:35.399Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/baaff7ce-e7e4-48bf-a109-459dce9dbdfc/value  </span></b>',\n            '{\\n     text: <span style=\"color:#0A0\">&#39;nightwatch&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;n&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.474Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/baaff7ce-e7e4-48bf-a109-459dce9dbdfc/value (75ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:35.482Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;button[type=submit]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.495Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (14ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;8e21ce02-77e5-49cb-9895-2f436159a21e&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.497Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;8e21ce02-77e5-49cb-9895-2f436159a21e&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;8e21ce02-77e5-49cb-9895-2f436159a21e&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.515Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync (18ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.520Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;button[type=submit]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.523Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (4ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;8e21ce02-77e5-49cb-9895-2f436159a21e&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.526Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/8e21ce02-77e5-49cb-9895-2f436159a21e/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:38.119Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/8e21ce02-77e5-49cb-9895-2f436159a21e/click (2593ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:38.124Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;.layout__content&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:38.127Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (3ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;37f690d8-76f0-42f1-a3cc-9f5a315171f8&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:38.128Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/37f690d8-76f0-42f1-a3cc-9f5a315171f8/text  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:38.687Z',\n            '  Response 200 GET /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/37f690d8-76f0-42f1-a3cc-9f5a315171f8/text (558ms)',\n            '{\\n     value: <span style=\"color:#0A0\">&#39;Search\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;https://nightwatchjs.org\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwatch.js | Node.js powered End-to-End testing framework\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwa...&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:38.706Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/6cb34613-0649-457f-a9db-e94b1ee7a079  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:39.278Z',\n            '  Response 200 DELETE /session/6cb34613-0649-457f-a9db-e94b1ee7a079 (573ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:19:31.753Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:33.066Z',\n            '  Response 200 POST /session (1314ms)',\n            '{\\n     value: {\\n       sessionId: \\'6cb34613-0649-457f-a9db-e94b1ee7a079\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93753,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofilekOpiU3\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:33.073Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/url  ',\n            '{ url: \\'https://www.ecosia.org/\\' }'\n          ],\n          [\n            '2023-04-06T10:19:35.294Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/url (2221ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:35.301Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  ',\n            '{ using: \\'css selector\\', value: \\'body\\' }'\n          ],\n          [\n            '2023-04-06T10:19:35.313Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (13ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'79fe3b43-6ef5-46f7-b81a-6ba5e43a97d0\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.315Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'79fe3b43-6ef5-46f7-b81a-6ba5e43a97d0\\',\\n         ELEMENT: \\'79fe3b43-6ef5-46f7-b81a-6ba5e43a97d0\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.326Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync (11ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:19:35.330Z',\n            '  Request GET /session/6cb34613-0649-457f-a9db-e94b1ee7a079/title  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:35.333Z',\n            '  Response 200 GET /session/6cb34613-0649-457f-a9db-e94b1ee7a079/title (3ms)',\n            '{ value: \\'Ecosia - the search engine that plants trees\\' }'\n          ],\n          [\n            '2023-04-06T10:19:35.339Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  ',\n            '{ using: \\'css selector\\', value: \\'input[type=search]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:35.348Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (9ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'baaff7ce-e7e4-48bf-a109-459dce9dbdfc\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.349Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'baaff7ce-e7e4-48bf-a109-459dce9dbdfc\\',\\n         ELEMENT: \\'baaff7ce-e7e4-48bf-a109-459dce9dbdfc\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.377Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync (28ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:19:35.379Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  ',\n            '{ using: \\'css selector\\', value: \\'input[type=search]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:35.385Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (6ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'baaff7ce-e7e4-48bf-a109-459dce9dbdfc\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.387Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/baaff7ce-e7e4-48bf-a109-459dce9dbdfc/clear  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:35.398Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/baaff7ce-e7e4-48bf-a109-459dce9dbdfc/clear (11ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:35.399Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/baaff7ce-e7e4-48bf-a109-459dce9dbdfc/value  ',\n            '{\\n     text: \\'nightwatch\\',\\n     value: [\\n       \\'n\\', \\'i\\', \\'g\\', \\'h\\',\\n       \\'t\\', \\'w\\', \\'a\\', \\'t\\',\\n       \\'c\\', \\'h\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.474Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/baaff7ce-e7e4-48bf-a109-459dce9dbdfc/value (75ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:35.482Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  ',\n            '{ using: \\'css selector\\', value: \\'button[type=submit]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:35.495Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (14ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'8e21ce02-77e5-49cb-9895-2f436159a21e\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.497Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'8e21ce02-77e5-49cb-9895-2f436159a21e\\',\\n         ELEMENT: \\'8e21ce02-77e5-49cb-9895-2f436159a21e\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.515Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/execute/sync (18ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:19:35.520Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  ',\n            '{ using: \\'css selector\\', value: \\'button[type=submit]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:35.523Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (4ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'8e21ce02-77e5-49cb-9895-2f436159a21e\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.526Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/8e21ce02-77e5-49cb-9895-2f436159a21e/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:38.119Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/8e21ce02-77e5-49cb-9895-2f436159a21e/click (2593ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:38.124Z',\n            '  Request POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements  ',\n            '{ using: \\'css selector\\', value: \\'.layout__content\\' }'\n          ],\n          [\n            '2023-04-06T10:19:38.127Z',\n            '  Response 200 POST /session/6cb34613-0649-457f-a9db-e94b1ee7a079/elements (3ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'37f690d8-76f0-42f1-a3cc-9f5a315171f8\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:38.128Z',\n            '  Request GET /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/37f690d8-76f0-42f1-a3cc-9f5a315171f8/text  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:38.687Z',\n            '  Response 200 GET /session/6cb34613-0649-457f-a9db-e94b1ee7a079/element/37f690d8-76f0-42f1-a3cc-9f5a315171f8/text (558ms)',\n            '{\\n     value: \\'Search\\\\n\\' +\\n       \\'https://nightwatchjs.org\\\\n\\' +\\n       \\'Nightwatch.js | Node.js powered End-to-End testing framework\\\\n\\' +\\n       \\'Nightwa...\\',\\n     suppressBase64Data: true\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:38.706Z',\n            '  Request DELETE /session/6cb34613-0649-457f-a9db-e94b1ee7a079  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:39.278Z',\n            '  Response 200 DELETE /session/6cb34613-0649-457f-a9db-e94b1ee7a079 (573ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      selectElement: {\n        reportPrefix: 'FIREFOX_111.0.1__',\n        assertionsCount: 1,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '1.082',\n        timeMs: 1082,\n        completed: {\n          demoTest: {\n            time: '1.082',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Forth option is selected (4ms)',\n                stackTrace: '',\n                fullMsg: 'Forth option is selected \\u001b[0;90m(4ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 1,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 1,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              demoTest: {\n                time: '1.082',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Forth option is selected \\u001b[0;90m(4ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Forth option is selected \\u001b[0;90m(4ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 1,\n                commands: [\n                ],\n                passed: 1,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 1082,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:41 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:42 GMT'\n              }\n            },\n            timeMs: 1082,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:41 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:42 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          demoTest: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'url',\n                args: [\n                  'https://www.selenium.dev/selenium/web/formPage.html'\n                ],\n                startTime: 1680776381835,\n                endTime: 1680776382638,\n                elapsedTime: 803,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'element().getAttribute',\n                args: [\n                  'tagName'\n                ],\n                startTime: 1680776382642,\n                endTime: 1680776382669,\n                elapsedTime: 27,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'element().findElement',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776382669,\n                endTime: 1680776382674,\n                elapsedTime: 5,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'perform',\n                args: [\n                  'function () { [native code] }'\n                ],\n                startTime: 1680776382639,\n                endTime: 1680776382900,\n                elapsedTime: 261,\n                status: 'pass'\n              },\n              {\n                name: 'element().findElement',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776382901,\n                endTime: 1680776382905,\n                elapsedTime: 4,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'assert.selected',\n                args: [\n                  '[object Object]',\n                  'Forth option is selected'\n                ],\n                startTime: 1680776382906,\n                endTime: 1680776382912,\n                elapsedTime: 6,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776382919,\n                endTime: 1680776384029,\n                elapsedTime: 1110,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 1,\n        group: '',\n        modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/selectElement.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:40 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:42 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'firefox',\n          browserVersion: '111.0.1',\n          'moz:accessibilityChecks': false,\n          'moz:buildID': '20230321111920',\n          'moz:geckodriverVersion': '0.32.0',\n          'moz:headless': false,\n          'moz:platformVersion': '22.3.0',\n          'moz:processID': 93822,\n          'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileHW3NPW',\n          'moz:shutdownTimeout': 60000,\n          'moz:useNonSpecCompliantPointerOrigin': false,\n          'moz:webdriverClick': true,\n          'moz:windowless': false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify'\n        },\n        sessionId: 'a1f5ad5e-07f5-4800-ba12-b7a271e609a9',\n        projectName: '',\n        buildName: '',\n        testEnv: 'firefox',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/selectElement_geckodriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:19:40.629Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:41.827Z',\n            '  Response 200 POST /session (1199ms)',\n            '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;a1f5ad5e-07f5-4800-ba12-b7a271e609a9&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93822<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileHW3NPW&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:41.837Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://www.selenium.dev/selenium/web/formPage.html&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.638Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/url (801ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:42.643Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;select[name=selectomatic]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.660Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/elements (17ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ab344c02-89da-455d-a6d9-f3d066201c38&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.661Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var h=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=h;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (43188 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ab344c02-89da-455d-a6d9-f3d066201c38&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;ab344c02-89da-455d-a6d9-f3d066201c38&#39;<span style=\"color:#FFF\">\\n       },\\n       <span style=\"color:#0A0\">&#39;tagName&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.668Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/execute/sync (7ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;SELECT&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.670Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;xpath&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;./option[. = &quot;Four&quot;]|./option[normalize-space(text()) = &quot;Four&quot;]|./optgroup/option[. = &quot;Four&quot;]|./optgroup/option[normalize-space(text()) = &quot;Four&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.674Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element (4ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f5aa1430-b88f-46cf-9816-c48c2ef74bfd&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.675Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.678Z',\n            '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected (3ms)',\n            '{ value: <span style=\"color:#A50\">false<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.679Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/enabled  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.687Z',\n            '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/enabled (9ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.688Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:42.900Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/click (212ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:42.901Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;option[value=four]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.905Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element (4ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f5aa1430-b88f-46cf-9816-c48c2ef74bfd&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.909Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.911Z',\n            '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected (3ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.921Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.026Z',\n            '  Response 200 DELETE /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9 (1105ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:19:40.629Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:41.827Z',\n            '  Response 200 POST /session (1199ms)',\n            '{\\n     value: {\\n       sessionId: \\'a1f5ad5e-07f5-4800-ba12-b7a271e609a9\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93822,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileHW3NPW\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:41.837Z',\n            '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/url  ',\n            '{ url: \\'https://www.selenium.dev/selenium/web/formPage.html\\' }'\n          ],\n          [\n            '2023-04-06T10:19:42.638Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/url (801ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:42.643Z',\n            '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/elements  ',\n            '{ using: \\'css selector\\', value: \\'select[name=selectomatic]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:42.660Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/elements (17ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ab344c02-89da-455d-a6d9-f3d066201c38\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:42.661Z',\n            '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var h=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=h;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (43188 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ab344c02-89da-455d-a6d9-f3d066201c38\\',\\n         ELEMENT: \\'ab344c02-89da-455d-a6d9-f3d066201c38\\'\\n       },\\n       \\'tagName\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:42.668Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/execute/sync (7ms)',\n            '{ value: \\'SELECT\\' }'\n          ],\n          [\n            '2023-04-06T10:19:42.670Z',\n            '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element  ',\n            '{\\n     using: \\'xpath\\',\\n     value: \\'./option[. = &quot;Four&quot;]|./option[normalize-space(text()) = &quot;Four&quot;]|./optgroup/option[. = &quot;Four&quot;]|./optgroup/option[normalize-space(text()) = &quot;Four&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:42.674Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element (4ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f5aa1430-b88f-46cf-9816-c48c2ef74bfd\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:42.675Z',\n            '  Request GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:42.678Z',\n            '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected (3ms)',\n            '{ value: false }'\n          ],\n          [\n            '2023-04-06T10:19:42.679Z',\n            '  Request GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/enabled  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:42.687Z',\n            '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/enabled (9ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:19:42.688Z',\n            '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:42.900Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/click (212ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:42.901Z',\n            '  Request POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element  ',\n            '{ using: \\'css selector\\', value: \\'option[value=four]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:42.905Z',\n            '  Response 200 POST /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/ab344c02-89da-455d-a6d9-f3d066201c38/element (4ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f5aa1430-b88f-46cf-9816-c48c2ef74bfd\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:42.909Z',\n            '  Request GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:42.911Z',\n            '  Response 200 GET /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9/element/f5aa1430-b88f-46cf-9816-c48c2ef74bfd/selected (3ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:19:42.921Z',\n            '  Request DELETE /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:44.026Z',\n            '  Response 200 DELETE /session/a1f5ad5e-07f5-4800-ba12-b7a271e609a9 (1105ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      'sample-with-relative-locators': {\n        reportPrefix: 'FIREFOX_111.0.1__',\n        assertionsCount: 5,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '0.09500',\n        timeMs: 95,\n        completed: {\n          'locate password input': {\n            time: '0.04600',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 20 milliseconds.',\n                stackTrace: '',\n                fullMsg: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 20 milliseconds.',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input (10ms)',\n                stackTrace: '',\n                fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (10ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \"password\" (10ms)',\n                stackTrace: '',\n                fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (10ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 3,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 3,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'locate password input': {\n                time: '0.04600',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 20 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 20 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (10ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (10ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (10ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (10ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 3,\n                commands: [\n                ],\n                passed: 3,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 46,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT'\n              }\n            },\n            timeMs: 46,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT'\n          },\n          'fill in password input': {\n            time: '0.04900',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Element <form.login-form> was visible after 9 milliseconds.',\n                stackTrace: '',\n                fullMsg: 'Element <form.login-form> was visible after 9 milliseconds.',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if value of element <input[type=password]> equals \\'password\\' (7ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if value of element \\u001b[0;33m<input[type=password]>\\u001b[0m equals \\u001b[0;33m\\'password\\'\\u001b[0m \\u001b[0;90m(7ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 2,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 2,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'locate password input': {\n                time: '0.04600',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 20 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> was visible after 20 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (10ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to be an input\\u001b[0;90m (10ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (10ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})> to have attribute \"type\" equal: \\u001b[0;33m\"password\"\\u001b[0m\\u001b[0;90m (10ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 3,\n                commands: [\n                ],\n                passed: 3,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 46,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT'\n              },\n              'fill in password input': {\n                time: '0.04900',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <form.login-form> was visible after 9 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <form.login-form> was visible after 9 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if value of element \\u001b[0;33m<input[type=password]>\\u001b[0m equals \\u001b[0;33m\\'password\\'\\u001b[0m \\u001b[0;90m(7ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if value of element \\u001b[0;33m<input[type=password]>\\u001b[0m equals \\u001b[0;33m\\'password\\'\\u001b[0m \\u001b[0;90m(7ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 2,\n                commands: [\n                ],\n                passed: 2,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 49,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT'\n              }\n            },\n            timeMs: 49,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://archive.org/account/login'\n                ],\n                startTime: 1680776378988,\n                endTime: 1680776383821,\n                elapsedTime: 4833,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'locate password input': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})'\n                ],\n                startTime: 1680776383825,\n                endTime: 1680776383847,\n                elapsedTime: 22,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'expect.element',\n                args: [\n                  'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})'\n                ],\n                startTime: 1680776383847,\n                endTime: 1680776383857,\n                elapsedTime: 10,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'expect.element',\n                args: [\n                  'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})'\n                ],\n                startTime: 1680776383857,\n                endTime: 1680776383867,\n                elapsedTime: 10,\n                status: 'pass',\n                result: {\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'fill in password input': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  'form.login-form'\n                ],\n                startTime: 1680776383869,\n                endTime: 1680776383878,\n                elapsedTime: 9,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'setValue',\n                args: [\n                  'RelativeBy({\"relative\":{\"root\":{\"tag name\":\"input\"},\"filters\":[{\"kind\":\"below\",\"args\":[{\"css selector\":\"input[type=email]\"}]}]}})',\n                  'password'\n                ],\n                startTime: 1680776383878,\n                endTime: 1680776383907,\n                elapsedTime: 29,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.valueEquals',\n                args: [\n                  'input[type=password]',\n                  'password'\n                ],\n                startTime: 1680776383908,\n                endTime: 1680776383917,\n                elapsedTime: 9,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                ],\n                startTime: 1680776383919,\n                endTime: 1680776384266,\n                elapsedTime: 347,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 2,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 5,\n        group: '',\n        modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/sample-with-relative-locators.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:37 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:43 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'firefox',\n          browserVersion: '111.0.1',\n          'moz:accessibilityChecks': false,\n          'moz:buildID': '20230321111920',\n          'moz:geckodriverVersion': '0.32.0',\n          'moz:headless': false,\n          'moz:platformVersion': '22.3.0',\n          'moz:processID': 93802,\n          'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileblN5O0',\n          'moz:shutdownTimeout': 60000,\n          'moz:useNonSpecCompliantPointerOrigin': false,\n          'moz:webdriverClick': true,\n          'moz:windowless': false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify'\n        },\n        sessionId: 'e778e563-6512-4f69-b72c-fe30bb5df801',\n        projectName: '',\n        buildName: '',\n        testEnv: 'firefox',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/sample-with-relative-locators_geckodriver.log',\n        host: 'localhost',\n        tests: 2,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:19:37.670Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:38.983Z',\n            '  Response 200 POST /session (1314ms)',\n            '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;e778e563-6512-4f69-b72c-fe30bb5df801&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93802<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileblN5O0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:38.990Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://archive.org/account/login&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.820Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/url (4831ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:43.828Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.839Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (12ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;698e20ed-f1e9-4bd3-9469-bc6001cc8926&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ed49daea-95cf-4c88-92b5-5091c9d0faae&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;c9f0afe9-4af4-4842-9da3-2fa454dd3bdb&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.841Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;698e20ed-f1e9-4bd3-9469-bc6001cc8926&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;698e20ed-f1e9-4bd3-9469-bc6001cc8926&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.846Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (6ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.848Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.854Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (5ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;698e20ed-f1e9-4bd3-9469-bc6001cc8926&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ed49daea-95cf-4c88-92b5-5091c9d0faae&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;c9f0afe9-4af4-4842-9da3-2fa454dd3bdb&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.855Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/name  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.856Z',\n            '  Response 200 GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/name (2ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.858Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.863Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (5ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;698e20ed-f1e9-4bd3-9469-bc6001cc8926&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ed49daea-95cf-4c88-92b5-5091c9d0faae&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;c9f0afe9-4af4-4842-9da3-2fa454dd3bdb&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.864Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/attribute/type  </span></b>',\n            '<span style=\"color:#555\">undefined<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.867Z',\n            '  Response 200 GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/attribute/type (3ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;password&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.870Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;form.login-form&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.872Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/elements (2ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;473d143d-3025-498e-9b71-7c7fdfca85e0&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.873Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;473d143d-3025-498e-9b71-7c7fdfca85e0&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;473d143d-3025-498e-9b71-7c7fdfca85e0&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.878Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (5ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.880Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         relative: { root: { <span style=\"color:#0A0\">&#39;tag name&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;input&#39;<span style=\"color:#FFF\"> }, filters: [ <span style=\"color:#0AA\">[Object]<span style=\"color:#FFF\"> ] }\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.889Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (10ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;698e20ed-f1e9-4bd3-9469-bc6001cc8926&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;ed49daea-95cf-4c88-92b5-5091c9d0faae&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;c9f0afe9-4af4-4842-9da3-2fa454dd3bdb&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.890Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/clear  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:43.895Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/clear (5ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:43.896Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/value  </span></b>',\n            '{\\n     text: <span style=\"color:#0A0\">&#39;password&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;p&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;o&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;r&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;d&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.907Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/value (11ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:43.911Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=password]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.913Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/elements (2ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;698e20ed-f1e9-4bd3-9469-bc6001cc8926&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.913Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/property/value  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.915Z',\n            '  Response 200 GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/property/value (2ms)',\n            '{ value: <span style=\"color:#0A0\">&#39;password&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.921Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/e778e563-6512-4f69-b72c-fe30bb5df801  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.265Z',\n            '  Response 200 DELETE /session/e778e563-6512-4f69-b72c-fe30bb5df801 (344ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:19:37.670Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:38.983Z',\n            '  Response 200 POST /session (1314ms)',\n            '{\\n     value: {\\n       sessionId: \\'e778e563-6512-4f69-b72c-fe30bb5df801\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93802,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileblN5O0\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:38.990Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/url  ',\n            '{ url: \\'https://archive.org/account/login\\' }'\n          ],\n          [\n            '2023-04-06T10:19:43.820Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/url (4831ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:43.828Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.839Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (12ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'698e20ed-f1e9-4bd3-9469-bc6001cc8926\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ed49daea-95cf-4c88-92b5-5091c9d0faae\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'c9f0afe9-4af4-4842-9da3-2fa454dd3bdb\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.841Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'698e20ed-f1e9-4bd3-9469-bc6001cc8926\\',\\n         ELEMENT: \\'698e20ed-f1e9-4bd3-9469-bc6001cc8926\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.846Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (6ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:19:43.848Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.854Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (5ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'698e20ed-f1e9-4bd3-9469-bc6001cc8926\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ed49daea-95cf-4c88-92b5-5091c9d0faae\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'c9f0afe9-4af4-4842-9da3-2fa454dd3bdb\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.855Z',\n            '  Request GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/name  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:43.856Z',\n            '  Response 200 GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/name (2ms)',\n            '{ value: \\'input\\' }'\n          ],\n          [\n            '2023-04-06T10:19:43.858Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.863Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (5ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'698e20ed-f1e9-4bd3-9469-bc6001cc8926\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ed49daea-95cf-4c88-92b5-5091c9d0faae\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'c9f0afe9-4af4-4842-9da3-2fa454dd3bdb\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.864Z',\n            '  Request GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/attribute/type  ',\n            'undefined'\n          ],\n          [\n            '2023-04-06T10:19:43.867Z',\n            '  Response 200 GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/attribute/type (3ms)',\n            '{ value: \\'password\\' }'\n          ],\n          [\n            '2023-04-06T10:19:43.870Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/elements  ',\n            '{ using: \\'css selector\\', value: \\'form.login-form\\' }'\n          ],\n          [\n            '2023-04-06T10:19:43.872Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/elements (2ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'473d143d-3025-498e-9b71-7c7fdfca85e0\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.873Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'473d143d-3025-498e-9b71-7c7fdfca85e0\\',\\n         ELEMENT: \\'473d143d-3025-498e-9b71-7c7fdfca85e0\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.878Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (5ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:19:43.880Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var aa=this||self;function ba(a){return&quot;string&quot;==typeof a}function ca(a,b){a=a.split(&quot;.&quot;);var c=aa;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;... (53855 characters)\\',\\n     args: [\\n       {\\n         relative: { root: { \\'tag name\\': \\'input\\' }, filters: [ [Object] ] }\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.889Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/execute/sync (10ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'698e20ed-f1e9-4bd3-9469-bc6001cc8926\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'ed49daea-95cf-4c88-92b5-5091c9d0faae\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'c9f0afe9-4af4-4842-9da3-2fa454dd3bdb\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.890Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/clear  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:43.895Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/clear (5ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:43.896Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/value  ',\n            '{\\n     text: \\'password\\',\\n     value: [\\n       \\'p\\', \\'a\\', \\'s\\',\\n       \\'s\\', \\'w\\', \\'o\\',\\n       \\'r\\', \\'d\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.907Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/value (11ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:43.911Z',\n            '  Request POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/elements  ',\n            '{ using: \\'css selector\\', value: \\'input[type=password]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:43.913Z',\n            '  Response 200 POST /session/e778e563-6512-4f69-b72c-fe30bb5df801/elements (2ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'698e20ed-f1e9-4bd3-9469-bc6001cc8926\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.913Z',\n            '  Request GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/property/value  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:43.915Z',\n            '  Response 200 GET /session/e778e563-6512-4f69-b72c-fe30bb5df801/element/698e20ed-f1e9-4bd3-9469-bc6001cc8926/property/value (2ms)',\n            '{ value: \\'password\\' }'\n          ],\n          [\n            '2023-04-06T10:19:43.921Z',\n            '  Request DELETE /session/e778e563-6512-4f69-b72c-fe30bb5df801  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:44.265Z',\n            '  Response 200 DELETE /session/e778e563-6512-4f69-b72c-fe30bb5df801 (344ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      shadowRootExample: {\n        reportPrefix: '',\n        assertionsCount: 0,\n        lastError: null,\n        skippedAtRuntime: [\n          'retrieve the shadowRoot'\n        ],\n        skipped: [\n          'retrieve the shadowRoot'\n        ],\n        time: 0,\n        completed: {\n        },\n        completedSections: {\n        },\n        errmessages: [\n        ],\n        testsCount: 0,\n        skippedCount: 1,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 0,\n        group: '',\n        modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/shadowRootExample.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:45 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:45 GMT',\n        sessionCapabilities: {\n          browserName: 'firefox',\n          alwaysMatch: {\n            acceptInsecureCerts: true,\n            'moz:firefoxOptions': {\n              args: [\n              ]\n            }\n          },\n          name: 'Shadow Root example test'\n        },\n        sessionId: '',\n        projectName: '',\n        buildName: '',\n        testEnv: 'firefox',\n        isMobile: false,\n        status: 'skip',\n        host: 'localhost',\n        tests: 0,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n        ],\n        rawHttpOutput: [\n        ]\n      },\n      google: {\n        reportPrefix: 'FIREFOX_111.0.1__',\n        assertionsCount: 2,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '10.68',\n        timeMs: 10675,\n        completed: {\n          'demo test using expect apis': {\n            time: '10.68',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n                stackTrace: '',\n                fullMsg: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Testing if element <#rso>:first-child> contains text \\'Nightwatch.js\\' (1069ms)',\n                stackTrace: '',\n                fullMsg: 'Testing if element \\u001b[0;33m<#rso>:first-child>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(1069ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 2,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 2,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'demo test using expect apis': {\n                time: '10.68',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n                    stackTrace: '',\n                    fullMsg: 'Element <form[action=\"/search\"] input[type=text]> was visible after 15 milliseconds.',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Testing if element \\u001b[0;33m<#rso>:first-child>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(1069ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Testing if element \\u001b[0;33m<#rso>:first-child>\\u001b[0m contains text \\u001b[0;33m\\'Nightwatch.js\\'\\u001b[0m \\u001b[0;90m(1069ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 2,\n                commands: [\n                ],\n                passed: 2,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 10675,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:35 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:46 GMT'\n              }\n            },\n            timeMs: 10675,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:35 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:46 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'demo test using expect apis': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'http://google.no'\n                ],\n                startTime: 1680776375516,\n                endTime: 1680776379577,\n                elapsedTime: 4061,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'isPresent',\n                args: [\n                  '[aria-modal=\"true\"][title=\"Before you continue to Google Search\"]'\n                ],\n                startTime: 1680776379578,\n                endTime: 1680776384672,\n                elapsedTime: 5094,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'waitForElementVisible',\n                args: [\n                  'form[action=\"/search\"] input[type=text]'\n                ],\n                startTime: 1680776384675,\n                endTime: 1680776384690,\n                elapsedTime: 15,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'sendKeys',\n                args: [\n                  'form[action=\"/search\"] input[type=text]',\n                  'Nightwatch.js,'\n                ],\n                startTime: 1680776384690,\n                endTime: 1680776384728,\n                elapsedTime: 38,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'assert.textContains',\n                args: [\n                  '#rso>:first-child',\n                  'Nightwatch.js'\n                ],\n                startTime: 1680776384728,\n                endTime: 1680776385800,\n                elapsedTime: 1072,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'end',\n                args: [\n                ],\n                startTime: 1680776385800,\n                endTime: 1680776386186,\n                elapsedTime: 386,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 2,\n        group: '',\n        modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/google.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:33 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:46 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'firefox',\n          browserVersion: '111.0.1',\n          'moz:accessibilityChecks': false,\n          'moz:buildID': '20230321111920',\n          'moz:geckodriverVersion': '0.32.0',\n          'moz:headless': false,\n          'moz:platformVersion': '22.3.0',\n          'moz:processID': 93775,\n          'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileoRDuKX',\n          'moz:shutdownTimeout': 60000,\n          'moz:useNonSpecCompliantPointerOrigin': false,\n          'moz:webdriverClick': true,\n          'moz:windowless': false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify'\n        },\n        sessionId: 'c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d',\n        projectName: '',\n        buildName: '',\n        testEnv: 'firefox',\n        isMobile: false,\n        status: 'pass',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:19:34.090Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.510Z',\n            '  Response 200 POST /session (1421ms)',\n            '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93775<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileoRDuKX&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:35.517Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;http://google.no&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:39.576Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/url (4059ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:39.580Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:39.588Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:40.091Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:40.096Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (6ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:40.598Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:40.600Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:41.103Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:41.111Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:41.614Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:41.620Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (7ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:42.123Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.128Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (6ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:42.630Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:42.637Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:43.140Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.154Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (15ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:43.656Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:43.659Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:44.161Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.163Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (2ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:44.665Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.669Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:44.676Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;form[action=&quot;/search&quot;] input[type=text]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.680Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;d11d4330-8ae2-44c8-b64a-3971618fbde5&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.682Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/execute/sync  </span></b>',\n            '{\\n     script: <span style=\"color:#0A0\">&#39;return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)&#39;<span style=\"color:#FFF\">,\\n     args: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;d11d4330-8ae2-44c8-b64a-3971618fbde5&#39;<span style=\"color:#FFF\">,\\n         ELEMENT: <span style=\"color:#0A0\">&#39;d11d4330-8ae2-44c8-b64a-3971618fbde5&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.689Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/execute/sync (7ms)',\n            '{ value: <span style=\"color:#A50\">true<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.691Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{\\n     using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">,\\n     value: <span style=\"color:#0A0\">&#39;form[action=&quot;/search&quot;] input[type=text]&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.694Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;d11d4330-8ae2-44c8-b64a-3971618fbde5&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.695Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/d11d4330-8ae2-44c8-b64a-3971618fbde5/value  </span></b>',\n            '{\\n     text: <span style=\"color:#0A0\">&#39;Nightwatch.js&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;N&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;.&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;j&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.727Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/d11d4330-8ae2-44c8-b64a-3971618fbde5/value (32ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:44.730Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#rso&gt;:first-child&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:44.732Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (2ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:45.235Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#rso&gt;:first-child&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:45.238Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:45.741Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#rso&gt;:first-child&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:45.744Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;1e7d46f7-02cf-45c5-9db9-6673572e7e78&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:45.746Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/1e7d46f7-02cf-45c5-9db9-6673572e7e78/text  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:45.797Z',\n            '  Response 200 GET /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/1e7d46f7-02cf-45c5-9db9-6673572e7e78/text (51ms)',\n            '{\\n     value: <span style=\"color:#0A0\">&#39;Web result with site links\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwatch.js | Node.js powered End-to-End testing framework\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Nightwatch....&#39;<span style=\"color:#FFF\">,\\n     suppressBase64Data: <span style=\"color:#A50\">true<span style=\"color:#FFF\">\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:45.803Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:46.185Z',\n            '  Response 200 DELETE /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d (383ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:19:34.090Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.510Z',\n            '  Response 200 POST /session (1421ms)',\n            '{\\n     value: {\\n       sessionId: \\'c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93775,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofileoRDuKX\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:35.517Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/url  ',\n            '{ url: \\'http://google.no\\' }'\n          ],\n          [\n            '2023-04-06T10:19:39.576Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/url (4059ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:39.580Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:39.588Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:40.091Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:40.096Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (6ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:40.598Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:40.600Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:41.103Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:41.111Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:41.614Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:41.620Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (7ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:42.123Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:42.128Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (6ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:42.630Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:42.637Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (8ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:43.140Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.154Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (15ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:43.656Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:43.659Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:44.161Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:44.163Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (2ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:44.665Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'[aria-modal=&quot;true&quot;][title=&quot;Before you continue to Google Search&quot;]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:44.669Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:44.676Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'form[action=&quot;/search&quot;] input[type=text]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:44.680Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'d11d4330-8ae2-44c8-b64a-3971618fbde5\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:44.682Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/execute/sync  ',\n            '{\\n     script: \\'return (function(){return (function(){var k=this||self;function aa(a){return&quot;string&quot;==typeof a}function ba(a,b){a=a.split(&quot;.&quot;);var c=k;a[0]in c||&quot;undefined&quot;==typeof c.execScript||c.execScript(&quot;var &quot;+a... (44027 characters)\\',\\n     args: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'d11d4330-8ae2-44c8-b64a-3971618fbde5\\',\\n         ELEMENT: \\'d11d4330-8ae2-44c8-b64a-3971618fbde5\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:44.689Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/execute/sync (7ms)',\n            '{ value: true }'\n          ],\n          [\n            '2023-04-06T10:19:44.691Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{\\n     using: \\'css selector\\',\\n     value: \\'form[action=&quot;/search&quot;] input[type=text]\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:44.694Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'d11d4330-8ae2-44c8-b64a-3971618fbde5\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:44.695Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/d11d4330-8ae2-44c8-b64a-3971618fbde5/value  ',\n            '{\\n     text: \\'Nightwatch.js\\',\\n     value: [\\n       \\'N\\', \\'i\\', \\'g\\', \\'h\\',\\n       \\'t\\', \\'w\\', \\'a\\', \\'t\\',\\n       \\'c\\', \\'h\\', \\'.\\', \\'j\\',\\n       \\'s\\', \\'\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:44.727Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/d11d4330-8ae2-44c8-b64a-3971618fbde5/value (32ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:44.730Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{ using: \\'css selector\\', value: \\'#rso&gt;:first-child\\' }'\n          ],\n          [\n            '2023-04-06T10:19:44.732Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (2ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:45.235Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{ using: \\'css selector\\', value: \\'#rso&gt;:first-child\\' }'\n          ],\n          [\n            '2023-04-06T10:19:45.238Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (4ms)',\n            '{ value: [] }'\n          ],\n          [\n            '2023-04-06T10:19:45.741Z',\n            '  Request POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements  ',\n            '{ using: \\'css selector\\', value: \\'#rso&gt;:first-child\\' }'\n          ],\n          [\n            '2023-04-06T10:19:45.744Z',\n            '  Response 200 POST /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/elements (3ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'1e7d46f7-02cf-45c5-9db9-6673572e7e78\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:45.746Z',\n            '  Request GET /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/1e7d46f7-02cf-45c5-9db9-6673572e7e78/text  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:45.797Z',\n            '  Response 200 GET /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d/element/1e7d46f7-02cf-45c5-9db9-6673572e7e78/text (51ms)',\n            '{\\n     value: \\'Web result with site links\\\\n\\' +\\n       \\'\\\\n\\' +\\n       \\'Nightwatch.js | Node.js powered End-to-End testing framework\\\\n\\' +\\n       \\'Nightwatch....\\',\\n     suppressBase64Data: true\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:45.803Z',\n            '  Request DELETE /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:46.185Z',\n            '  Response 200 DELETE /session/c72af4c6-ebcd-4db4-8c9e-a9b8d593a88d (383ms)',\n            '{ value: null }'\n          ]\n        ]\n      },\n      vueTodoList: {\n        reportPrefix: 'FIREFOX_111.0.1__',\n        assertionsCount: 3,\n        lastError: null,\n        skippedAtRuntime: [\n        ],\n        skipped: [\n        ],\n        time: '1.251',\n        timeMs: 1251,\n        completed: {\n          'should add a todo using global element()': {\n            time: '1.251',\n            assertions: [\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected elements <#todo-list ul li> count to equal: \"5\" (4ms)',\n                stackTrace: '',\n                fullMsg: 'Expected elements <#todo-list ul li> count to equal: \\u001b[0;33m\"5\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected element <#todo-list ul li> text to contain: \"what is nightwatch?\" (15ms)',\n                stackTrace: '',\n                fullMsg: 'Expected element <#todo-list ul li> text to contain: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n                failure: false\n              },\n              {\n                name: 'NightwatchAssertError',\n                message: 'Expected elements <#todo-list ul li input:checked> count to equal: \"3\" (4ms)',\n                stackTrace: '',\n                fullMsg: 'Expected elements <#todo-list ul li input:checked> count to equal: \\u001b[0;33m\"3\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n                failure: false\n              }\n            ],\n            commands: [\n            ],\n            passed: 3,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 3,\n            status: 'pass',\n            steps: [\n            ],\n            stackTrace: '',\n            testcases: {\n              'should add a todo using global element()': {\n                time: '1.251',\n                assertions: [\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected elements <#todo-list ul li> count to equal: \\u001b[0;33m\"5\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected elements <#todo-list ul li> count to equal: \\u001b[0;33m\"5\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected element <#todo-list ul li> text to contain: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected element <#todo-list ul li> text to contain: \\u001b[0;33m\"what is nightwatch?\"\\u001b[0m\\u001b[0;90m (15ms)\\u001b[0m',\n                    failure: false\n                  },\n                  {\n                    name: 'NightwatchAssertError',\n                    message: 'Expected elements <#todo-list ul li input:checked> count to equal: \\u001b[0;33m\"3\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n                    stackTrace: '',\n                    fullMsg: 'Expected elements <#todo-list ul li input:checked> count to equal: \\u001b[0;33m\"3\"\\u001b[0m\\u001b[0;90m (4ms)\\u001b[0m',\n                    failure: false\n                  }\n                ],\n                tests: 3,\n                commands: [\n                ],\n                passed: 3,\n                errors: 0,\n                failed: 0,\n                skipped: 0,\n                status: 'pass',\n                steps: [\n                ],\n                stackTrace: '',\n                timeMs: 1251,\n                startTimestamp: 'Thu, 06 Apr 2023 10:19:47 GMT',\n                endTimestamp: 'Thu, 06 Apr 2023 10:19:48 GMT'\n              }\n            },\n            timeMs: 1251,\n            startTimestamp: 'Thu, 06 Apr 2023 10:19:47 GMT',\n            endTimestamp: 'Thu, 06 Apr 2023 10:19:48 GMT'\n          }\n        },\n        completedSections: {\n          __global_beforeEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __before_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          'should add a todo using global element()': {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'navigateTo',\n                args: [\n                  'https://todo-vue3-vite.netlify.app/'\n                ],\n                startTime: 1680776387084,\n                endTime: 1680776387841,\n                elapsedTime: 757,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'sendKeys',\n                args: [\n                  '#new-todo-input',\n                  'what is nightwatch?'\n                ],\n                startTime: 1680776387841,\n                endTime: 1680776387864,\n                elapsedTime: 23,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'click',\n                args: [\n                  'form button[type=\"submit\"]'\n                ],\n                startTime: 1680776387865,\n                endTime: 1680776388087,\n                elapsedTime: 222,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'expect.elements',\n                args: [\n                  '#todo-list ul li'\n                ],\n                startTime: 1680776388091,\n                endTime: 1680776388095,\n                elapsedTime: 4,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'expect.element',\n                args: [\n                  '#todo-list ul li'\n                ],\n                startTime: 1680776388096,\n                endTime: 1680776388111,\n                elapsedTime: 15,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'element().findElement',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776388111,\n                endTime: 1680776388114,\n                elapsedTime: 3,\n                status: 'pass',\n                result: {\n                }\n              },\n              {\n                name: 'click',\n                args: [\n                  '[object Object]'\n                ],\n                startTime: 1680776388116,\n                endTime: 1680776388327,\n                elapsedTime: 211,\n                status: 'pass',\n                result: {\n                  status: 0\n                }\n              },\n              {\n                name: 'expect.elements',\n                args: [\n                  '#todo-list ul li input:checked'\n                ],\n                startTime: 1680776388328,\n                endTime: 1680776388332,\n                elapsedTime: 4,\n                status: 'pass',\n                result: {\n                }\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __after_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          },\n          __global_afterEach_hook: {\n            time: 0,\n            assertions: [\n            ],\n            commands: [\n              {\n                name: 'end',\n                args: [\n                  'true'\n                ],\n                startTime: 1680776388337,\n                endTime: 1680776389341,\n                elapsedTime: 1004,\n                status: 'pass'\n              }\n            ],\n            passed: 0,\n            errors: 0,\n            failed: 0,\n            skipped: 0,\n            tests: 0,\n            status: 'pass'\n          }\n        },\n        errmessages: [\n        ],\n        testsCount: 1,\n        skippedCount: 0,\n        failedCount: 0,\n        errorsCount: 0,\n        passedCount: 3,\n        group: '',\n        modulePath: '/Users/vaibhavsingh/Dev/nightwatch/examples/tests/vueTodoList.js',\n        startTimestamp: 'Thu, 06 Apr 2023 10:19:45 GMT',\n        endTimestamp: 'Thu, 06 Apr 2023 10:19:48 GMT',\n        sessionCapabilities: {\n          acceptInsecureCerts: false,\n          browserName: 'firefox',\n          browserVersion: '111.0.1',\n          'moz:accessibilityChecks': false,\n          'moz:buildID': '20230321111920',\n          'moz:geckodriverVersion': '0.32.0',\n          'moz:headless': false,\n          'moz:platformVersion': '22.3.0',\n          'moz:processID': 93855,\n          'moz:profile': '/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile2iTSVu',\n          'moz:shutdownTimeout': 60000,\n          'moz:useNonSpecCompliantPointerOrigin': false,\n          'moz:webdriverClick': true,\n          'moz:windowless': false,\n          pageLoadStrategy: 'normal',\n          platformName: 'mac',\n          proxy: {\n          },\n          setWindowRect: true,\n          strictFileInteractability: false,\n          timeouts: {\n            implicit: 0,\n            pageLoad: 300000,\n            script: 30000\n          },\n          unhandledPromptBehavior: 'dismiss and notify'\n        },\n        sessionId: '02cdc21b-3ae3-4f80-b595-07f8498c4a11',\n        projectName: '',\n        buildName: '',\n        testEnv: 'firefox',\n        isMobile: false,\n        status: 'pass',\n        seleniumLog: '/Users/vaibhavsingh/Dev/nightwatch/logs/vueTodoList_geckodriver.log',\n        host: 'localhost',\n        tests: 1,\n        failures: 0,\n        errors: 0,\n        httpOutput: [\n          [\n            '2023-04-06T10:19:45.864Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session  </span></b>',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\"> } }\\n  }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:47.078Z',\n            '  Response 200 POST /session (1217ms)',\n            '{\\n     value: {\\n       sessionId: <span style=\"color:#0A0\">&#39;02cdc21b-3ae3-4f80-b595-07f8498c4a11&#39;<span style=\"color:#FFF\">,\\n       capabilities: {\\n         acceptInsecureCerts: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         browserName: <span style=\"color:#0A0\">&#39;firefox&#39;<span style=\"color:#FFF\">,\\n         browserVersion: <span style=\"color:#0A0\">&#39;111.0.1&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:accessibilityChecks&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:buildID&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;20230321111920&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:geckodriverVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;0.32.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:headless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:platformVersion&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;22.3.0&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:processID&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">93855<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:profile&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile2iTSVu&#39;<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:shutdownTimeout&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">60000<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:useNonSpecCompliantPointerOrigin&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:webdriverClick&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         <span style=\"color:#0A0\">&#39;moz:windowless&#39;<span style=\"color:#FFF\">: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         pageLoadStrategy: <span style=\"color:#0A0\">&#39;normal&#39;<span style=\"color:#FFF\">,\\n         platformName: <span style=\"color:#0A0\">&#39;mac&#39;<span style=\"color:#FFF\">,\\n         proxy: {},\\n         setWindowRect: <span style=\"color:#A50\">true<span style=\"color:#FFF\">,\\n         strictFileInteractability: <span style=\"color:#A50\">false<span style=\"color:#FFF\">,\\n         timeouts: { implicit: <span style=\"color:#A50\">0<span style=\"color:#FFF\">, pageLoad: <span style=\"color:#A50\">300000<span style=\"color:#FFF\">, script: <span style=\"color:#A50\">30000<span style=\"color:#FFF\"> },\\n         unhandledPromptBehavior: <span style=\"color:#0A0\">&#39;dismiss and notify&#39;<span style=\"color:#FFF\">\\n       }\\n     }\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:47.085Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/url  </span></b>',\n            '{ url: <span style=\"color:#0A0\">&#39;https://todo-vue3-vite.netlify.app/&#39;<span style=\"color:#FFF\"> }</span></span>'\n          ],\n          [\n            '2023-04-06T10:19:47.840Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/url (755ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:47.843Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#new-todo-input&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:47.848Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (6ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;cbf47355-2c00-4daf-b3b5-8179d43d1e88&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:47.851Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/cbf47355-2c00-4daf-b3b5-8179d43d1e88/value  </span></b>',\n            '{\\n     text: <span style=\"color:#0A0\">&#39;what is nightwatch?&#39;<span style=\"color:#FFF\">,\\n     value: [\\n       <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;s&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39; &#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;n&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;i&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;g&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;w&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;a&#39;<span style=\"color:#FFF\">,\\n       <span style=\"color:#0A0\">&#39;t&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;c&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;h&#39;<span style=\"color:#FFF\">, <span style=\"color:#0A0\">&#39;?&#39;<span style=\"color:#FFF\">\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:47.863Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/cbf47355-2c00-4daf-b3b5-8179d43d1e88/value (13ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:47.867Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;form button[type=&quot;submit&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:47.871Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:47.873Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:48.087Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed/click (215ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:48.092Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#todo-list ul li&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:48.094Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9fba7102-78a1-4f16-8085-471f605574cf&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;d8c3dbca-d8d8-4395-bdee-5dd16a889d37&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;320b0952-82ca-4c8d-b91b-36141f695c14&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f8514d2e-85c6-4991-8920-31e10a6d7f88&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;2bfecd6d-d71c-4946-97bd-5521f6a31055&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:48.096Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#todo-list ul li&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:48.098Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9fba7102-78a1-4f16-8085-471f605574cf&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;d8c3dbca-d8d8-4395-bdee-5dd16a889d37&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;320b0952-82ca-4c8d-b91b-36141f695c14&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;f8514d2e-85c6-4991-8920-31e10a6d7f88&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;2bfecd6d-d71c-4946-97bd-5521f6a31055&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:48.099Z',\n            '  Request <b><span style=\"color:#0AA\">GET /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/text  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:48.110Z',\n            '  Response 200 GET /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/text (11ms)',\n            '{\\n     value: <span style=\"color:#0A0\">&#39;new taskwhat is nightwatch?\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Edit\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;New Taskwhat Is Nightwatch?\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;Delete\\\\n&#39;<span style=\"color:#FFF\"> +\\n       <span style=\"color:#0A0\">&#39;New Taskwhat Is Nightwatch?&#39;<span style=\"color:#FFF\">\\n  }</span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:48.112Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/element  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;input[type=&quot;checkbox&quot;]&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:48.114Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/element (2ms)',\n            '{\\n     value: {\\n       <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9db02cb5-bb43-4ef1-b935-38a417240ee2&#39;<span style=\"color:#FFF\">\\n     }\\n  }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:48.117Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/9db02cb5-bb43-4ef1-b935-38a417240ee2/click  </span></b>',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:48.327Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/9db02cb5-bb43-4ef1-b935-38a417240ee2/click (209ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ],\n          [\n            '2023-04-06T10:19:48.329Z',\n            '  Request <b><span style=\"color:#0AA\">POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  </span></b>',\n            '{ using: <span style=\"color:#0A0\">&#39;css selector&#39;<span style=\"color:#FFF\">, value: <span style=\"color:#0A0\">&#39;#todo-list ul li input:checked&#39;<span style=\"color:#FFF\"> }</span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:48.331Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n            '{\\n     value: [\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;a6373a47-f735-4162-bb2d-36b5aa4756a4&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;56a696cc-b2f5-4300-8428-0bcf93409417&#39;<span style=\"color:#FFF\">\\n       },\\n       {\\n         <span style=\"color:#0A0\">&#39;element-6066-11e4-a52e-4f735466cecf&#39;<span style=\"color:#FFF\">: <span style=\"color:#0A0\">&#39;9db02cb5-bb43-4ef1-b935-38a417240ee2&#39;<span style=\"color:#FFF\">\\n       }\\n     ]\\n  }</span></span></span></span></span></span></span></span></span></span></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:48.340Z',\n            '  Request <b><span style=\"color:#0AA\">DELETE /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11  </span></b>',\n            '<span style=\"color:#0A0\">&#39;&#39;<span style=\"color:#FFF\"></span></span>'\n          ],\n          [\n            '2023-04-06T10:19:49.340Z',\n            '  Response 200 DELETE /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11 (1000ms)',\n            '{ value: <b>null<span style=\"font-weight:normal;text-decoration:none;font-style:normal\"> }</span></b>'\n          ]\n        ],\n        rawHttpOutput: [\n          [\n            '2023-04-06T10:19:45.864Z',\n            '  Request POST /session  ',\n            '{\\n     capabilities: { firstMatch: [ {} ], alwaysMatch: { browserName: \\'firefox\\' } }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:47.078Z',\n            '  Response 200 POST /session (1217ms)',\n            '{\\n     value: {\\n       sessionId: \\'02cdc21b-3ae3-4f80-b595-07f8498c4a11\\',\\n       capabilities: {\\n         acceptInsecureCerts: false,\\n         browserName: \\'firefox\\',\\n         browserVersion: \\'111.0.1\\',\\n         \\'moz:accessibilityChecks\\': false,\\n         \\'moz:buildID\\': \\'20230321111920\\',\\n         \\'moz:geckodriverVersion\\': \\'0.32.0\\',\\n         \\'moz:headless\\': false,\\n         \\'moz:platformVersion\\': \\'22.3.0\\',\\n         \\'moz:processID\\': 93855,\\n         \\'moz:profile\\': \\'/var/folders/3j/vnc2ktf17bq7qtb8qstq1fk40000gq/T/rust_mozprofile2iTSVu\\',\\n         \\'moz:shutdownTimeout\\': 60000,\\n         \\'moz:useNonSpecCompliantPointerOrigin\\': false,\\n         \\'moz:webdriverClick\\': true,\\n         \\'moz:windowless\\': false,\\n         pageLoadStrategy: \\'normal\\',\\n         platformName: \\'mac\\',\\n         proxy: {},\\n         setWindowRect: true,\\n         strictFileInteractability: false,\\n         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },\\n         unhandledPromptBehavior: \\'dismiss and notify\\'\\n       }\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:47.085Z',\n            '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/url  ',\n            '{ url: \\'https://todo-vue3-vite.netlify.app/\\' }'\n          ],\n          [\n            '2023-04-06T10:19:47.840Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/url (755ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:47.843Z',\n            '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  ',\n            '{ using: \\'css selector\\', value: \\'#new-todo-input\\' }'\n          ],\n          [\n            '2023-04-06T10:19:47.848Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (6ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'cbf47355-2c00-4daf-b3b5-8179d43d1e88\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:47.851Z',\n            '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/cbf47355-2c00-4daf-b3b5-8179d43d1e88/value  ',\n            '{\\n     text: \\'what is nightwatch?\\',\\n     value: [\\n       \\'w\\', \\'h\\', \\'a\\', \\'t\\', \\' \\',\\n       \\'i\\', \\'s\\', \\' \\', \\'n\\', \\'i\\',\\n       \\'g\\', \\'h\\', \\'t\\', \\'w\\', \\'a\\',\\n       \\'t\\', \\'c\\', \\'h\\', \\'?\\'\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:47.863Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/cbf47355-2c00-4daf-b3b5-8179d43d1e88/value (13ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:47.867Z',\n            '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  ',\n            '{ using: \\'css selector\\', value: \\'form button[type=&quot;submit&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:47.871Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (5ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:47.873Z',\n            '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:48.087Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/4588a889-58e9-4d3d-87e4-ab0e6fe6d9ed/click (215ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:48.092Z',\n            '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  ',\n            '{ using: \\'css selector\\', value: \\'#todo-list ul li\\' }'\n          ],\n          [\n            '2023-04-06T10:19:48.094Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9fba7102-78a1-4f16-8085-471f605574cf\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'d8c3dbca-d8d8-4395-bdee-5dd16a889d37\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'320b0952-82ca-4c8d-b91b-36141f695c14\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f8514d2e-85c6-4991-8920-31e10a6d7f88\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'2bfecd6d-d71c-4946-97bd-5521f6a31055\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:48.096Z',\n            '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  ',\n            '{ using: \\'css selector\\', value: \\'#todo-list ul li\\' }'\n          ],\n          [\n            '2023-04-06T10:19:48.098Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9fba7102-78a1-4f16-8085-471f605574cf\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'d8c3dbca-d8d8-4395-bdee-5dd16a889d37\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'320b0952-82ca-4c8d-b91b-36141f695c14\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'f8514d2e-85c6-4991-8920-31e10a6d7f88\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'2bfecd6d-d71c-4946-97bd-5521f6a31055\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:48.099Z',\n            '  Request GET /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/text  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:48.110Z',\n            '  Response 200 GET /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/text (11ms)',\n            '{\\n     value: \\'new taskwhat is nightwatch?\\\\n\\' +\\n       \\'Edit\\\\n\\' +\\n       \\'New Taskwhat Is Nightwatch?\\\\n\\' +\\n       \\'Delete\\\\n\\' +\\n       \\'New Taskwhat Is Nightwatch?\\'\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:48.112Z',\n            '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/element  ',\n            '{ using: \\'css selector\\', value: \\'input[type=&quot;checkbox&quot;]\\' }'\n          ],\n          [\n            '2023-04-06T10:19:48.114Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/2bfecd6d-d71c-4946-97bd-5521f6a31055/element (2ms)',\n            '{\\n     value: {\\n       \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9db02cb5-bb43-4ef1-b935-38a417240ee2\\'\\n     }\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:48.117Z',\n            '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/9db02cb5-bb43-4ef1-b935-38a417240ee2/click  ',\n            '{}'\n          ],\n          [\n            '2023-04-06T10:19:48.327Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/element/9db02cb5-bb43-4ef1-b935-38a417240ee2/click (209ms)',\n            '{ value: null }'\n          ],\n          [\n            '2023-04-06T10:19:48.329Z',\n            '  Request POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements  ',\n            '{ using: \\'css selector\\', value: \\'#todo-list ul li input:checked\\' }'\n          ],\n          [\n            '2023-04-06T10:19:48.331Z',\n            '  Response 200 POST /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11/elements (2ms)',\n            '{\\n     value: [\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'a6373a47-f735-4162-bb2d-36b5aa4756a4\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'56a696cc-b2f5-4300-8428-0bcf93409417\\'\\n       },\\n       {\\n         \\'element-6066-11e4-a52e-4f735466cecf\\': \\'9db02cb5-bb43-4ef1-b935-38a417240ee2\\'\\n       }\\n     ]\\n  }'\n          ],\n          [\n            '2023-04-06T10:19:48.340Z',\n            '  Request DELETE /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11  ',\n            '\\'\\''\n          ],\n          [\n            '2023-04-06T10:19:49.340Z',\n            '  Response 200 DELETE /session/02cdc21b-3ae3-4f80-b595-07f8498c4a11 (1000ms)',\n            '{ value: null }'\n          ]\n        ]\n      }\n    }\n  },\n  elapsedTime: '94.14',\n  startTimestamp: 'Thu, 06 Apr 2023 10:18:28 GMT',\n  endTimestamp: 'Thu, 06 Apr 2023 10:20:02 GMT',\n  lastError: {\n    name: 'NightwatchAssertError',\n    message: 'Timed out while waiting for element <#search_form_input_homepage> to be present for 5000 milliseconds. - expected \\u001b[0;32m\"visible\"\\u001b[0m but got: \\u001b[0;31m\"not found\"\\u001b[0m \\u001b[0;90m(5088ms)\\u001b[0m',\n    showDiff: false,\n    abortOnFailure: true,\n    waitFor: true,\n    stack: 'Error\\n    at DescribeInstance.<anonymous> (/Users/vaibhavsingh/Dev/nightwatch/examples/tests/duckDuckGo.js:8:8)\\n    at Context.call (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/context.js:478:35)\\n    at TestCase.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/testcase.js:58:31)\\n    at Runnable.__runFn (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:80)\\n    at Runnable.run (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/runnable.js:126:21)\\n    at TestSuite.executeRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:912:49)\\n    at TestSuite.handleRunnable (/Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:927:33)\\n    at /Users/vaibhavsingh/Dev/nightwatch/lib/testsuite/index.js:759:21\\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at async DefaultRunner.runTestSuite (/Users/vaibhavsingh/Dev/nightwatch/lib/runner/test-runners/default.js:78:7)'\n  }\n};\n"
  },
  {
    "path": "test/extra/reporter/custom.js",
    "content": "module.exports = {\n  write: function(results, options, done) {\n    done();\n  }\n};"
  },
  {
    "path": "test/extra/reporter/notvalid.js",
    "content": "module.exports = {\n\n};"
  },
  {
    "path": "test/extra/withgeckodriver-concurrent.json",
    "content": "{\n  \"src_folders\" : [\"../sampletests\"],\n  \"output_folder\" : \"./output\",\n  \"custom_commands_path\" : \"\",\n  \"custom_assertions_path\" : \"\",\n  \"globals_path\" : \"./globals.js\",\n  \"test_workers\" : {\n    \"enabled\" : true\n  },\n\n  \"output\" : false,\n\n  \"test_settings\": {\n    \"default\" : {\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      },\n      \"webdriver\": {\n        \"start_process\": true,\n        \"server_path\": \"./geckodriver\"\n      }\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/withmocha.json",
    "content": "{\n  \"src_folders\" : [\"./test/mochatests\"],\n  \"output_folder\" : \"./output\",\n  \"custom_commands_path\" : \"\",\n  \"custom_assertions_path\" : \"\",\n  \"output\" : false,\n  \"selenium\" : {\n    \"start_process\" : false,\n    \"server_path\" : \"./bin/selenium-server.jar\"\n  },\n  \"test_runner\" : \"mocha\",\n  \"test_settings\": {\n    \"default\" : {\n      \"selenium_port\" : 10195,\n      \"silent\" : true,\n      \"persist_globals\" : true,\n      \"globals\" : {},\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      }\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/extra/withsafari-concurrent.json",
    "content": "{\n  \"src_folders\" : [\"../sampletests\"],\n  \"output_folder\" : \"./output\",\n  \"custom_commands_path\" : \"\",\n  \"custom_assertions_path\" : \"\",\n  \"globals_path\" : \"./globals.js\",\n  \"test_workers\" : {\n    \"enabled\" : true\n  },\n\n  \"output\" : false,\n\n  \"test_settings\": {\n    \"default\" : {\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"safari\"\n      },\n      \"webdriver\": {\n        \"start_process\": true\n      }\n    },\n    \"chrome\" : {\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"chrome\"\n      },\n      \"webdriver\": {\n        \"start_process\": true\n      }\n    },\n    \"firefox\" : {\n      \"desiredCapabilities\" : {\n        \"browserName\" : \"firefox\"\n      },\n      \"webdriver\": {\n        \"start_process\": true\n      }\n    }\n  }\n}\n\n\n"
  },
  {
    "path": "test/lib/command-mocks.js",
    "content": "const MockServer = require('./mockserver.js');\n\nlet server;\nmodule.exports = {\n  start(done) {\n    server = MockServer.init();\n    server.on('listening', function () {\n      done();\n    });\n  },\n\n  stop(done) {\n    if (!server) {\n      done();\n\n      return;\n    }\n\n    server.close(function () {\n      done();\n    });\n  },\n\n  createServer(opts = {}) {\n    return MockServer.initAsync(opts);\n  },\n\n  cookieFound(name = 'test_cookie', value = '123456', {times = 0} = {}) {\n    MockServer.addMock({\n      url: `/wd/hub/session/1352110219202/cookie/${name}`,\n      method: 'GET',\n      response: {\n        sessionId: '1352110219202',\n        status: 0,\n        value: {\n          name: name,\n          value: value,\n          path: '/',\n          domain: 'example.org',\n          secure: false\n        }\n      },\n      times\n    }, times === 0);\n  },\n\n  cookieNotFound(name = 'other_cookie', {times = 0} = {}) {\n    MockServer.addMock({\n      url: `/wd/hub/session/1352110219202/cookie/${name}`,\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        value: {\n          error: 'no such cookie',\n          message: 'no such cookie',\n          stacktrace: ''\n        }\n      }),\n      statusCode: 404,\n      times\n    }, times === 0);\n  },\n\n  cookiesFound({times = 0} = {}) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/cookie',\n      method: 'GET',\n      response: {\n        sessionId: '1352110219202',\n        status: 0,\n        value: [{\n          name: 'test_cookie',\n          value: '123456',\n          path: '/',\n          domain: 'example.org',\n          secure: false\n        }]\n      },\n      times\n    }, times === 0);\n  },\n\n  cookiesNotFound({times = 0} = {}) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/cookie',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: []\n      }),\n      times\n    }, times === 0);\n  },\n\n  cookiesSocketDelay({times = 0} = {}) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/cookie',\n      method: 'GET',\n      socketDelay: 200,\n      response: '',\n      times\n    }, times === 0);\n  },\n\n  deleteCookie() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/cookie/other_cookie',\n      method: 'DELETE',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0\n      })\n    }, true);\n  },\n\n  deleteCookies() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/cookie',\n      method: 'DELETE',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: null\n      })\n    }, true);\n  },\n\n  addCookie() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/cookie',\n      method: 'POST',\n      postdata: JSON.stringify(\n        {\n          cookie: {\n            name: 'other_cookie',\n            value: '123456',\n            secure: false,\n            httpOnly: false\n          }\n        }\n      ),\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n  },\n\n  elementSelected(elementId = '0') {\n    MockServer.addMock({\n      url: `/wd/hub/session/1352110219202/element/${elementId}/selected`,\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        value: true,\n        status: 0\n      })\n    }, true);\n  },\n\n  element({ \n    using = 'css selector', \n    value = '#container',\n    response = {\n      value: [{\n        'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n      }]\n    }\n  }) {\n    MockServer.addMock({\n      url: '/wd/hub/session/13521-10219-202/elements',\n      method: 'POST',\n      postdata: JSON.stringify({using, value}),\n\n      response: JSON.stringify(response)\n    }, true);\n  },\n\n  elementNotSelected(elementId = '0') {\n    MockServer.addMock({\n      url: `/wd/hub/session/1352110219202/element/${elementId}/selected`,\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        value: false,\n        status: 0\n      })\n    }, true);\n  },\n\n  maximizeWindow() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/window/current/maximize',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0\n      })\n    }, true);\n  },\n\n  /**\n   * @deprecated\n   * @param elementId\n   * @param text\n   */\n  elementText(elementId = '0', text = 'sample text') {\n    MockServer.addMock({\n      url: `/wd/hub/session/1352110219202/element/${elementId}/text`,\n      method: 'GET',\n      response: JSON.stringify({\n        sessiondId: '1352110219202',\n        status: 0,\n        value: text\n      })\n    });\n  },\n\n  tagName(elementId = '0', tagName = 'div') {\n    MockServer.addMock({\n      url: `/wd/hub/session/1352110219202/element/${elementId}/name`,\n      method: 'GET',\n      response: JSON.stringify({\n        value: tagName\n      })\n    });\n  },\n\n  clearElement(elementId = '0') {\n    MockServer.addMock({\n      url: `/wd/hub/session/1352110219202/element/${elementId}/clear`,\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    });\n  },\n\n  executeSync(response, {times = 0} = {}) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify(response),\n      times\n    });\n\n    return this;\n  },\n\n  visible(elementId = '0', value = true, {times = 0} = {}) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value\n      }),\n      times\n    });\n\n    return this;\n  },\n\n  w3cVisible(value = true) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value\n      })\n    }, true);\n  },\n  \n  w3cSelected(elementId = '5cc459b8-36a8-3042-8b4a-258883ea642b', value = true) {\n    MockServer.addMock({\n      url: `/session/13521-10219-202/element/${elementId}/selected`,\n      method: 'GET',\n      response: JSON.stringify({\n        value\n      })\n    }, true);\n  },\n  \n  w3cEnabled(elementId = '5cc459b8-36a8-3042-8b4a-258883ea642b', value = true) {\n    MockServer.addMock({\n      url: `/session/13521-10219-202/element/${elementId}/enabled`,\n      method: 'GET',\n      response: JSON.stringify({\n        value\n      })\n    });\n  },\n\n  findElements({using = 'css selector', value = '#container', response = null, times = 0}) {\n    const mockOpts = {\n      url: '/session/13521-10219-202/elements',\n      method: 'POST',\n      postdata: JSON.stringify({using, value}),\n      response: JSON.stringify(response)\n    };\n\n    if (times > 0) {\n      mockOpts.times = times;\n    }\n\n    MockServer.addMock(mockOpts, times === 0);\n\n    return this;\n  },\n\n  getElementText({elementId, responseText, sessionId = '13521-10219-202'}) {\n    MockServer.addMock({\n      url: `/session/${sessionId}/element/${elementId}/text`,\n      method: 'GET',\n      response: JSON.stringify({\n        value: responseText\n      })\n    });\n\n    return this;\n  },\n\n  findElementFromParent({elementId, sessionId = '13521-10219-202', response}) {\n    MockServer.addMock({\n      url: `/session/${sessionId}/element/${elementId}/element`,\n      method: 'POST',\n      response: JSON.stringify(response)\n    });\n\n    return this;\n  },\n\n  clickElement({elementId, sessionId = '13521-10219-202'}) {\n    MockServer.addMock({\n      url: `/session/${sessionId}/element/${elementId}/click`,\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    });\n\n    return this;\n  },\n\n  elementProperty(elementId, property, response) {\n    MockServer.addMock({\n      url: `/wd/hub/session/1352110219202/element/${elementId}/property/${property}`,\n      method: 'GET',\n      response: JSON.stringify(response)\n    });\n\n    return this;\n  },\n\n  setElementValue({\n    sessionId = '13521-10219-202',\n    elementId,\n    text,\n    times = 0,\n    response = null,\n    statusCode = 200\n  }) {\n    MockServer.addMock({\n      url: `/session/${sessionId}/element/${elementId}/value`,\n      method: 'POST',\n      postdata: JSON.stringify({\n        text,\n        value: text.split('')\n      }),\n      response: response || {\n        value: null\n      },\n      statusCode\n    }, times === 0);\n\n    return this;\n  },\n\n  frame({\n    sessionId = '13521-10219-202',\n    elementId = '5cc459b8-36a8-3042-8b4a-258883ea642b',\n    text,\n    times = 0,\n    response = null,\n    statusCode = 200\n  } = {}) {\n    MockServer.addMock({\n      url: `/session/${sessionId}/frame`,\n      method: 'POST',\n      postdata: JSON.stringify({\n        id: {\n          'element-6066-11e4-a52e-4f735466cecf': elementId,\n          ELEMENT: elementId\n        }\n      }),\n      response: response || {\n        value: null\n      },\n      statusCode\n    }, times === 0);\n\n    return this;\n  },\n\n  createFirefoxSession({\n    persist = false,\n    sessionId = '13521-10219-202',\n    headless = true,\n    deleteSession = true,\n    url = '/wd/hub/session'\n  }) {\n    const browserName = 'firefox';\n    const headlessOpt = headless ? '-headless' : '';\n    const options = {\n      ['moz:firefoxOptions']: {\n        prefs: {'remote.active-protocols': 3},\n        args: [headlessOpt]\n      }\n    };\n\n    MockServer.addMock({\n      url,\n      statusCode: 201,\n      method: 'POST',\n      postdata: JSON.stringify({\n        capabilities: {firstMatch: [{}], alwaysMatch: {browserName, ...options}}\n      }),\n\n      response: JSON.stringify({\n        value: {\n          sessionId,\n          capabilities: {\n            acceptInsecureCerts: false,\n            browserName: 'firefox',\n            browserVersion: '65.0.1'\n          }\n        }\n      })\n    }, !persist);\n\n    if (!deleteSession) {\n      return;\n    }\n\n    MockServer.addMock({\n      url: `/session/${sessionId}`,\n      method: 'DELETE',\n      response: {\n        value: null\n      }\n    }, !persist);\n  },\n\n  createChromeSession({\n    persist = false,\n    sessionId = '13521-10219-202',\n    headless = true,\n    deleteSession = true,\n    url = '/wd/hub/session',\n    times = 0\n  }) {\n    const browserName = 'chrome';\n    const headlessOpt = headless ? 'headless=new' : '';\n    const options = {\n      ['goog:chromeOptions']: {}\n    };\n\n    if (headlessOpt) {\n      options['goog:chromeOptions'].args = [headlessOpt];\n    }\n\n    MockServer.addMock({\n      url,\n      statusCode: 201,\n      method: 'POST',\n      postdata: JSON.stringify({\n        capabilities: {firstMatch: [{}], alwaysMatch: {browserName, ...options}}\n      }),\n      times,\n      response: JSON.stringify({\n        value: {\n          sessionId,\n          capabilities: {\n            acceptInsecureCerts: false,\n            browserName: 'chrome',\n            browserVersion: '90'\n          }\n        }\n      })\n    }, !persist);\n\n    if (!deleteSession) {\n      return this;\n    }\n\n    MockServer.addMock({\n      url: `${url}/${sessionId}`,\n      method: 'DELETE',\n      times,\n      response: {\n        value: null\n      }\n    }, !persist);\n\n    return this;\n  },\n\n  createNewW3CSession({\n    testName = '',\n    browserName = 'firefox',\n    sessionId = '13521-10219-202',\n    persist = false,\n    deleteSession = true,\n    postdata = null\n  } = {}) {\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 201,\n      method: 'POST',\n      postdata: JSON.stringify(postdata || {\n        capabilities: {firstMatch: [{}], alwaysMatch: {browserName}}\n      }),\n\n      response: JSON.stringify({\n        value: {\n          sessionId,\n          capabilities: {\n            acceptInsecureCerts: false,\n            browserName,\n            browserVersion: '65.0.1'\n          }\n        }\n      })\n    }, !persist);\n\n    if (!deleteSession) {\n      return;\n    }\n\n    MockServer.addMock({\n      url: `/session/${sessionId}`,\n      method: 'DELETE',\n      response: {\n        value: null\n      }\n    }, !persist);\n\n    return this;\n  },\n\n  navigateTo({url, persist = false, sessionId = '13521-10219-202'}) {\n    MockServer.addMock({\n      url: `/session/${sessionId}/url`,\n      method: 'POST',\n      postdata: JSON.stringify({\n        url\n      }),\n      response: {\n        value: null\n      }\n    }, !persist);\n\n    return this;\n  }\n};\n"
  },
  {
    "path": "test/lib/fakedriver.js",
    "content": "const {WebElement} = require('selenium-webdriver');\n\nconst CommandsExecutor = {\n  findChildElement(args, assertion) {\n    assertion({args, command: 'findChildElement'});\n\n    return fakeWebElement(TEST_CHILD_ELEMENT_ID);\n  },\n\n  findChildElements(args, assertion) {\n    assertion({args, command: 'findChildElements'});\n\n    return [fakeWebElement(TEST_CHILD_ELEMENT_ID)];\n  },\n\n  clearElement(args, assertion) {\n    assertion({args, command: 'clearElement'});\n\n    return null;\n  },\n\n  isElementSelected(args, assertion) {\n    assertion({args, command: 'isElementSelected'});\n\n    return true;\n  },\n\n  isElementEnabled(args, assertion) {\n    assertion({args, command: 'isElementEnabled'});\n\n    return true;\n  },\n\n  isElementDisplayed(args, assertion) {\n    assertion({args, command: 'isElementDisplayed'});\n\n    return true;\n  },\n\n  getElementAttribute(args, assertion) {\n    assertion({args, command: 'getElementAttribute'});\n\n    return 'test_value';\n  },\n\n  getElementProperty(args, assertion) {\n    assertion({args, command: 'getElementProperty'});\n\n    return 'test_prop_value';\n  },\n\n  getElementTagName(args, assertion) {\n    assertion({args, command: 'getElementTagName'});\n\n    return 'div';\n  },\n\n  getElementText(args, assertion) {\n    assertion({args, command: 'getElementText'});\n\n    return 'text';\n  },\n\n  clickElement(args, assertion) {\n    assertion({args, command: 'clickElement'});\n\n    return null;\n  },\n\n  getElementRect(args, assertion) {\n    assertion({args, command: 'getElementRect'});\n\n    return {\n      width: 100,\n      height: 105,\n      x: 10,\n      y: 15\n    };\n  },\n\n  getElementValueOfCssProperty(args, assertion) {\n    assertion({args, command: 'getElementValueOfCssProperty'});\n\n    return '';\n  },\n\n  sendKeysToElement(args, assertion) {\n    assertion({args, command: 'sendKeysToElement'});\n\n    return null;\n  },\n\n  submitElement(webElement, assertion) {\n    assertion({webElement, command: 'submit'});\n\n    return null;\n  }\n};\n\nconst fakeWebElement = function(elementId) {\n  return {\n    getId() {\n      return Promise.resolve(elementId);\n    }\n  };\n};\n\nconst fakeSeleniumElement =  function(driver, elementId) {\n  driver.execute =  function(command) {\n    const commandName = command.getName();\n    const params = command.getParameters();\n\n    let result = CommandsExecutor[commandName](params, function(){});\n    if (!(result instanceof Promise)) {\n      result = Promise.resolve(result);\n    }\n\n    return result;\n  };\n\n  return new WebElement(driver, elementId);\n};\n\nconst TEST_ELEMENT_ID = '12345-6789';\nconst TEST_CHILD_ELEMENT_ID = '6789-192111';\n\nconst createElementCommandMocks = function(assertion) {\n  return {\n    findElement(locator) {\n      assertion({locator, command: 'findElement'});\n\n      return fakeWebElement(TEST_ELEMENT_ID);\n    },\n\n    findElements(locator) {\n      assertion({locator, command: 'findElements'});\n\n      const element = fakeWebElement(TEST_ELEMENT_ID);\n\n      return [\n        element\n      ];\n    }\n  };\n};\n\nconst createGenericCommandMocks = function(assertion) {\n  return {\n    getPageSource() {\n      assertion({\n        command: 'getPageSource'\n      });\n\n      return '<html><body></body></html>';\n    },\n\n    getSession() {\n      return {\n        sessionId: '123'\n      };\n    },\n\n    quit() {\n      return;\n    },\n\n    setFileDetector() {\n      assertion({\n        command: 'setFileDetector'\n      });\n\n      return;\n    },\n\n    executeScript(script, ...args) {\n      assertion({\n        command: 'executeScript',\n        script,\n        args\n      });\n\n      return null;\n    },\n    executeAsyncScript(script, ...args) {\n      assertion({\n        command: 'executeAsyncScript',\n        script,\n        args\n      });\n\n      return null;\n    },\n    takeScreenshot() {\n      assertion({\n        command: 'screenshot'\n      });\n\n      return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';\n    },\n    getTitle() {\n      assertion({\n        command: 'title'\n      });\n\n      return 'nightwatch';\n    },\n\n    getWindowHandle() {\n      assertion({\n        command: 'windowHandle'\n      });\n\n      return 'CDwindow-BE13CA812F066254342F4FEB180D14ED';\n    },\n    getAllWindowHandles() {\n      assertion({\n        command: 'windowHandles'\n      });\n\n      return ['CDwindow-BE13CA812F066254342F4FEB180D14ED'];\n    },\n    close() {\n      assertion({\n        command: 'window'\n      });\n\n      return null;\n    }\n  };\n};\n\nconst createWaitCommandMocks = function (assertion, args) {\n  return {\n    async wait(condn) {\n      assertion({\n        description: condn.description(), result: await condn.fn({\n          getCurrentUrl() {\n            return Promise.resolve(...args);\n          },\n          getTitle() {\n            return Promise.resolve(...args);\n          },\n          findElements(locator) {\n            const element = fakeWebElement(TEST_ELEMENT_ID);\n\n            return Promise.resolve([\n              element\n            ]);\n          },\n\n          switchTo() {\n            return {\n              frame() {\n                return Promise.resolve(null);\n              },\n              parentFrame() {\n                return Promise.resolve(null);\n              },\n              alert() {\n                return Promise.resolve({\n                  accept() {\n                    return null;\n                  },\n                  dismiss() {\n                    return null;\n                  },\n                  getText() {\n                    return Promise.resolve('alert text');\n                  },\n                  sendKeys(value) {\n                    return null;\n                  }\n                });\n              }\n            };\n          }\n        })\n      });\n\n      return Promise.resolve();\n    }\n  };\n};\n\nconst createManageCommandMocks = function(assertion) {\n  return {\n    manage() {\n      return {\n        addCookie(cookie) {\n          assertion(cookie);\n        },\n        deleteCookie(cookie) {\n          assertion(cookie);\n        },\n        deleteAllCookies() {\n          assertion({\n            command: 'deleteAllCookies'\n          });\n        },\n        getCookies() {\n          assertion('cookie-test');\n\n          return Promise.resolve();\n        },\n\n        window() {\n          return {\n            setRect(...args) {\n              assertion({\n                args\n              });\n\n              return Promise.resolve({value: null});\n            },\n            getRect(...args) {\n              return Promise.resolve({\n                x: 10,\n                y: 10,\n                width: 100,\n                height: 100\n              });\n            },\n            minimize() {\n              assertion({\n                command: 'minimizeWindow'\n              });\n\n              return null;\n            },\n            maximize() {\n              assertion({\n                command: 'windowMaximize'\n              });\n\n              return null;\n            }\n          };\n        },\n\n        logs() {\n          return {\n            get(type) {\n              assertion({\n                command: 'sessionLog'\n              });\n\n              return [{ \n                level: 'WARNING',\n                message: 'https://cdn-static.ecosia.org/manifest.json - Manifest: property \\'start_url\\' ignored, should be same origin as document.',\n                source: 'other',\n                timestamp: 1628690813925 \n              }]; \n            },\n            getAvailableLogTypes() {\n              assertion({\n                command: 'sessionLogTypes'\n              });\n\n              return ['browser', 'driver'];\n            }\n          };\n        },\n\n        setTimeouts(data) {\n          assertion({data, command: 'timeouts'});\n\n          return null;\n        }\n      };\n    }\n  };\n};\n\nconst createNavigateCommandMocks = function(assertion) {\n  return {\n    navigate() {\n      return {\n        to(url) {\n          assertion({url, command: 'url'});\n\n          return null;\n        },\n        back() {\n          assertion();\n        },\n        refresh() {\n          assertion();\n        },\n        forward() {\n          assertion();\n        }\n      };\n    },\n    getCurrentUrl() {\n      assertion({command: 'url'});\n\n      return 'http://localhost';\n    }\n  };\n};\n\nmodule.exports = {\n  fakeWebElement,\n  fakeSeleniumElement,\n  create(assertion, mockDriverOverrides, args) {\n    const driver = {\n      execute(command) {\n        const commandName = command.getName();\n        const params = command.getParameters();\n\n        let result = CommandsExecutor[commandName](params, assertion);\n        if (!(result instanceof Promise)) {\n          result = Promise.resolve(result);\n        }\n\n        return result;\n      },\n\n      actions() {\n        return {\n          move(options) {\n            return {\n              perform() {\n                return null;\n              }\n            };\n          }\n        };\n      },\n\n      switchTo() {\n        return {\n          activeElement() {\n            assertion({command: 'activeElement'});\n\n            return fakeWebElement(TEST_ELEMENT_ID);\n          },\n          alert() {\n            return {\n              accept() {\n                assertion();\n\n                return null;\n              },\n              dismiss() {\n                assertion();\n\n                return null;\n              },\n              getText() {\n                assertion('alert text');\n\n                return Promise.resolve('alert text');\n              },\n              sendKeys(value) {\n                assertion(value);\n\n                return null;\n              }\n            };\n          },\n          frame(frameId) {\n            assertion(frameId);\n\n            return null;\n          },\n\n          parentFrame() {\n            return null;\n          },\n\n          window(handleOrName) {\n            assertion({\n              command: 'window',\n              name: handleOrName\n            });\n\n            return null;\n          },\n          newWindow(type){\n            assertion({\n              command: 'openNewWindow',\n              type\n            });\n\n            return null;\n          }\n        };\n      }\n    };\n\n    Object.assign(driver, createElementCommandMocks(assertion));\n    Object.assign(driver, createNavigateCommandMocks(assertion));\n    Object.assign(driver, createManageCommandMocks(assertion));\n    Object.assign(driver, createGenericCommandMocks(assertion));\n    Object.assign(driver, createWaitCommandMocks(assertion, args));\n    Object.assign(driver, mockDriverOverrides);\n\n    return driver;\n  },\n  createChromeDriver(assertion, mockDriverOverrides) {\n    const chromeDriver = {\n      launchApp(id) {\n        assertion({id, command: 'launchApp'});\n\n        return Promise.resolve({value: null});\n      },\n      getNetworkConditions() {\n        assertion({command: 'getNetworkConditions'});\n\n        return Promise.resolve({\n          value: {\n            download_throughput: 460800,\n            latency: 50000,\n            offline: false,\n            upload_throughput: 153600\n          }\n        });\n      },\n      setNetworkConditions(spec) {\n        assertion({spec, command: 'setNetworkConditions'});\n\n        return Promise.resolve({\n          value: null\n        });\n      },\n      sendDevToolsCommand(cmd, params) {\n        assertion({cmd, params, command: 'sendDevToolsCommand'});\n\n        return Promise.resolve({\n          value: null\n        });\n      },\n      sendAndGetDevToolsCommand(cmd, params) {\n        assertion({cmd, params, command: 'sendAndGetDevToolsCommand'});\n\n        return Promise.resolve({\n          value: {\n            jsVersion: '9.2.230.29',\n            product: 'Chrome/92.0.4515.159',\n            protocolVersion: '1.3',\n            revision: '@0185b8a19c88c5dfd3e6c0da6686d799e9bc3b52',\n            userAgent:\n              'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'\n          }\n        });\n      },\n      setDownloadPath(path) {\n        assertion({path, command: 'setDownloadPath'});\n\n        return Promise.resolve({\n          value: null\n        });\n      }\n    };\n\n    Object.assign(chromeDriver, mockDriverOverrides);\n\n    return chromeDriver;\n  },\n  createFirefoxDriver(assertion, mockDriverOverrides) {\n    const firefoxDriver = {\n      getContext() {\n        assertion({command: 'getContext'});\n\n        return Promise.resolve({value: 'content'});\n      },\n      setContext(context) {\n        assertion({context, command: 'setContext'});\n\n        return Promise.resolve({value: null});\n      },\n      installAddon(path) {\n        assertion({path, command: 'installAddon'});\n\n        return Promise.resolve({value: '0c20aa29-db90-4eae-a3bb-012c6ae180b1'});\n      },\n      uninstallAddon(id) {\n        assertion({id, command: 'uninstallAddon'});\n\n        return Promise.resolve({value: null});\n      }\n    };\n\n    Object.assign(firefoxDriver, mockDriverOverrides);\n\n    return firefoxDriver;\n  }\n};\n"
  },
  {
    "path": "test/lib/globals/commands-w3c.js",
    "content": "const MockServer  = require('../mockserver.js');\nconst Nightwatch = require('../nightwatch.js');\n\nmodule.exports = {\n  beforeEach(done, settings) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      Nightwatch.initClient(Object.assign({\n        selenium: {\n          port: null,\n          host: null,\n          start_process: false\n        },\n        webdriver: {\n          port: 10195,\n          host: 'localhost'\n        },\n        output: process.env.VERBOSE === '1' || false,\n        silent: false\n      }, settings))\n        .then(client => {\n          this.client = client;\n          done();\n        });\n    });\n    \n  },\n\n  afterEach(done) {\n    this.server.close(function() {\n      done();\n    });\n  }\n};\n"
  },
  {
    "path": "test/lib/globals/commands.js",
    "content": "const MockServer  = require('../mockserver.js');\nconst Nightwatch = require('../nightwatch.js');\n\nconst Commands = {\n  beforeEach(done, settings = {}) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      Nightwatch.initClient(Object.assign({\n        desiredCapabilities: {\n          name: 'testSuite'\n        },\n        selenium: {\n          port: 10195,\n          start_process: false\n        },\n        output: process.env.VERBOSE === '1' || false,\n        silent: false\n      }, settings))\n        .then(client => {\n          this.client = client;\n          done();\n        });\n    });\n  },\n\n  afterEach(done) {\n    this.server.close(function() {\n      done();\n    });\n  }\n};\n\nmodule.exports = Commands;\n"
  },
  {
    "path": "test/lib/globals/expect.js",
    "content": "const Nocks = require('../nocks.js');\nconst Nightwatch = require('../nightwatch.js');\n\nmodule.exports = {\n  beforeEach(opts, done) {\n    if (arguments.length === 1) {\n      done = arguments[0];\n      opts = {};\n    }\n\n    Nocks.cleanAll().createSession().enable();\n    Nightwatch.init(opts, function () {\n      done();\n    });\n\n    this.client = Nightwatch.client();\n  },\n\n  afterEach(done) {\n    //Nocks.deleteSession();\n    Nocks.disable();\n    this.client = null;\n    done();\n  },\n\n  runExpectAssertion({element = '#weblogin', fn, assertion}) {\n    const expect = this.client.api.expect.element(element);\n    fn(expect);\n\n    return this.client.start(function() {\n      assertion(expect.assertion);\n    });\n  }\n};\n"
  },
  {
    "path": "test/lib/globals.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst assert = require('assert');\nconst lodashMerge = require('lodash/merge');\nconst common = require('../common.js');\nconst Settings = common.require('settings/settings.js');\nconst Runner = common.require('runner/runner.js');\nconst Reporter = common.require('reporter/index.js');\nconst FakeDriver = require('./fakedriver.js');\nconst Nightwatch = require('../lib/nightwatch.js');\nconst MockServer  = require('../lib/mockserver.js');\n\nclass ExtendedReporter extends Reporter {\n  registerPassed(message) {\n    this.assertionMessage = message;\n\n    super.registerPassed(message);\n  }\n\n  logAssertResult(result) {\n    this.assertionResult = result;\n\n    super.logAssertResult(result);\n  }\n}\n\nclass Globals {\n  runGroupGlobal(client, hookName, done) {\n    const groupGlobal = path.join(__dirname, './globals/', client.currentTest.group.toLowerCase() + '.js');\n\n    fs.stat(groupGlobal, function(err, stats) {\n      if (err) {\n        return done();\n      }\n\n      const global = require(groupGlobal);\n\n      if (global[hookName]) {\n        global[hookName].call(global, done);\n      } else {\n        done();\n      }\n    });\n  }\n\n  beforeEach(client, done) {\n    if (client.currentTest.group) {\n      this.runGroupGlobal(client, 'beforeEach', done);\n    } else {\n      done();\n    }\n  }\n\n  afterEach(client, done) {\n    if (client.currentTest.group) {\n      this.runGroupGlobal(client, 'afterEach', done);\n    } else {\n      done();\n    }\n  }\n\n  protocolAfter(done) {\n    if (this.client) {\n      this.client = null;\n    }\n    if (this.wdClient) {\n      this.wdClient = null;\n    }\n\n    if (this.server) {\n      this.server.close(() => done());\n    } else {\n      done();\n    }\n  }\n\n  async protocolBefore(opts = {}, done) {\n    this.client = await Nightwatch.createClient(opts).initialize();\n\n    this.wdClient = await Nightwatch.createClient({\n      selenium: {\n        version2: false,\n        start_process: false\n      },\n      webdriver: {\n        start_process: true\n      }\n    }).initialize();\n\n    this.client.sessionId = this.client.api.sessionId = '1352110219202';\n    this.wdClient.sessionId = this.wdClient.api.sessionId = '1352110219202';\n\n    if (typeof done == 'function') {\n      this.server = MockServer.init();\n      this.server.on('listening', () => done());\n    }\n  }\n\n  protocolTest(definition) {\n    return this.runProtocolTest(definition, this.client);\n  }\n\n  protocolTestWebdriver(definition) {\n    return this.runProtocolTest(definition, this.wdClient);\n  }\n\n  runProtocolTest({assertion = function() {}, commandName, args = [], mockDriverOverrides = {}, browserDriver = ''}, client) {\n    return new Promise((resolve, reject) => {\n      client.transport.runProtocolAction = function(opts) {\n        assertion(opts);\n      };\n\n      client.elementLocator.sendElementsAction = function({transportAction, args}) {\n        //assertion(opts);\n        return this.transport.executeProtocolAction(transportAction, args);\n      };\n\n      let driver;\n\n      if (browserDriver === 'chrome') {\n        driver = FakeDriver.createChromeDriver(assertion, mockDriverOverrides);\n      } else if (browserDriver === 'firefox') {\n        driver = FakeDriver.createFirefoxDriver(assertion, mockDriverOverrides);\n      } else {\n        driver = FakeDriver.create(assertion, mockDriverOverrides, args);\n      }\n\n      client.transport.driver = driver;\n\n      if (args[0] === '@seleniumElement') {\n        args[0] = FakeDriver.fakeSeleniumElement(client.transport.driver, '12345-6789');\n      }\n\n      client.queue.tree.empty().createRootNode();\n\n      client.isES6AsyncTestcase = true;\n\n      try {\n        this.runApiCommand(commandName, args, client)\n          .then(result => {\n            if (result instanceof Error) {\n              reject(result);\n            } else {\n              resolve(result);\n            }\n          })\n          .catch(err => {\n            reject(err);\n          });\n      } catch (err) {\n        reject(err);\n      }\n    });\n  }\n\n  runApiCommand(commandName, args, client = this.client) {\n    let context;\n    let commandFn;\n    const namespace = commandName.split('.');\n\n    if (namespace.length === 1) {\n      context = client.api;\n      commandFn = context[commandName];\n    } else {\n      context = client.api[namespace[0]];\n      if (namespace[2]) {\n        context = context[namespace[1]];\n        commandFn = context[namespace[2]];\n      } else {\n        commandFn = context[namespace[1]];\n      }\n    }\n\n    return commandFn.apply(client.api, args);\n  }\n\n  startTestRunner(testsPath, suppliedSettings) {\n    const settings = Settings.parse(suppliedSettings);\n    const runner = Runner.create(settings, {\n      reporter: 'junit'\n    });\n\n    if (!Array.isArray(testsPath)) {\n      testsPath = [testsPath];\n    }\n\n    return Runner\n      .readTestSource(settings, {\n        _source: testsPath\n      })\n      .then(modules => {\n        return runner.run(modules);\n      })\n      .then(_ => {\n        return runner;\n      });\n  }\n\n  createReporter() {\n    const reporter = new ExtendedReporter({\n      settings: this.client.settings\n    });\n\n    this.client.setReporter(reporter);\n  }\n}\n\nmodule.exports = new Globals();\nfunction addSettings(settings) {\n  return lodashMerge({\n    globals: {\n      retryAssertionTimeout: 5,\n      waitForConditionPollInterval: 3\n    },\n    output: false,\n    silent: false\n  }, settings);\n}\n\nmodule.exports.assertion = async function(assertionName, api, {\n  args = [],\n  commandResult = {},\n  assertArgs = false,\n  assertError = false,\n  assertMessage = false,\n  assertFailure = false,\n  assertResult = false,\n  negate = false,\n  assertApiCommandArgs,\n  assertion = function() {},\n  settings = {}\n}) {\n  const instance = new Globals();\n  const options = addSettings(settings);\n  await instance.protocolBefore(options);\n\n  return new Promise((resolve, reject) => {\n    // initialize\n    const onFinish = function(err) {\n      instance.protocolAfter(() => {\n        if (err) {\n          reject(err);\n\n          return;\n        }\n\n        resolve();\n      });\n    };\n\n    let context;\n    let queueOpts;\n\n    // add API command\n    if (api) {\n      instance.client.api[api] = function(...fnArgs) {\n        if (assertArgs) {\n          if (typeof args[0] == 'string') {\n            assert.deepStrictEqual(fnArgs[0], {\n              selector: args[0],\n              suppressNotFoundErrors: true\n            });\n          } else {\n            assert.deepStrictEqual(fnArgs[0], args[0]);\n          }\n\n          if (fnArgs.length > 2) {\n            assert.strictEqual(fnArgs[1], args[1]);\n          }\n        } else if (assertApiCommandArgs) {\n          assertApiCommandArgs(fnArgs);\n        }\n\n        const callback = fnArgs[fnArgs.length - 1];\n        callback(typeof commandResult == 'function' ? commandResult() : commandResult);\n      };\n    }\n\n    // intercept add to queue and store the context and options\n    const {client} = instance;\n    const addToQueue = client.queue.add;\n    client.queue.add = function(opts) {\n      context = opts.context;\n      queueOpts = opts.options;\n      addToQueue.call(this, opts);\n    };\n\n    client.queue.done = function(err) {\n      this.emit('queue:finished', err);\n    };\n\n    // create an extended reporter so we can intercept the results\n    instance.createReporter();\n\n    // when the queue has finished running, signal the end of the test\n    client.queue.once('queue:finished', err => {\n      if (err && err.name !== 'NightwatchAssertError') {\n        onFinish(err);\n\n        return;\n      }\n\n      try {\n        // Run common assertions\n        if (assertError) {\n          assert.ok(err instanceof Error);\n          assert.strictEqual(err.name, 'NightwatchAssertError');\n        }\n\n        const assertionInstance = context.instance;\n        const {reporter} = client;\n\n        if (assertArgs) {\n          assert.deepStrictEqual(assertionInstance.args, args);\n          assert.deepStrictEqual(assertionInstance.retryAssertionTimeout, undefined);\n          assert.deepStrictEqual(assertionInstance.rescheduleInterval, undefined);\n        }\n\n        if (assertFailure) {\n          assert.strictEqual(assertionInstance.hasFailure(), true);\n          assert.strictEqual(assertionInstance.isOk(assertionInstance.getValue()), false);\n        }\n\n        if (assertMessage) {\n          const message = args[args.length - 1];\n          assert.strictEqual(assertionInstance.message, message);\n          assert.ok(typeof reporter.assertionMessage != 'undefined', 'assertionMessage is undefined');\n          assert.ok(reporter.assertionMessage.startsWith(message), reporter.assertionMessage);\n        }\n\n        if (assertResult) {\n          assert.deepStrictEqual(assertionInstance.result, commandResult);\n        }\n\n        const {failure, message} = client.reporter.assertionResult;\n        assertion({reporter, instance: assertionInstance, err, queueOpts, failure, message});\n\n        onFinish();\n      } catch (ex) {\n        onFinish(ex);\n      }\n    });\n\n    // run the assertion\n    const negateStr = negate ? 'not.' : '';\n    instance.runApiCommand(`assert.${negateStr}${assertionName}`, args);\n  });\n\n};\n"
  },
  {
    "path": "test/lib/mochatest.js",
    "content": "const CommandGlobals = require('./globals/commands.js');\n\nmodule.exports = {\n  addBefore: function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  },\n\n  addAfter: function(done) {\n    CommandGlobals.afterEach.call(this, function() {\n      done();\n    });\n  },\n\n  add: function(key, body) {\n    var result = {};\n\n    result[key] = body;\n\n    result[key].before = this.addBefore;\n    result[key].after = this.addAfter;\n\n    return result;\n  }\n};\n"
  },
  {
    "path": "test/lib/mockclient.js",
    "content": "class MockClient {\n  get options() {\n    return this.settings;\n  }\n\n  get session() {\n    return {\n      commandQueue: {\n        add: (...args) => {\n          return this.addToQueueFn.apply(this, args);\n        }\n      }\n    };\n  }\n\n  constructor(settings, reporter = {}, addToQueueFn = function() {}) {\n    this.settings = settings;\n    this.addToQueueFn = addToQueueFn;\n    this.locateStrategy = '';\n\n    this.setLocateStrategy();\n\n    this.api = {\n      assert: {},\n      page: {},\n      verify: {},\n      globals: {\n        retryAssertionTimeout: 5,\n        waitForConditionPollInterval: 10\n      }\n    };\n\n    if (settings.globals) {\n      Object.assign(this.api.globals, settings.globals);\n    }\n\n    this.client = {\n      options: this.settings,\n      api: this.api,\n      locateStrategy: this.locateStrategy\n    };\n\n    this.reporter = reporter;\n  }\n\n  setLocateStrategy() {\n    this.locateStrategy = this.settings.use_xpath ? 'xpath' : 'css selector';\n\n    return this;\n  }\n\n  isApiMethodDefined(commandName, namespace) {\n    return false;\n  }\n\n  setApiMethod(commandName, namespace, commandFn) {\n    this.api[namespace] = this.api[namespace] || {};\n\n    this.api[namespace][commandName] = function(...args) {\n      return commandFn.apply(this, args);\n    };\n\n    return this;\n  }\n}\n\nmodule.exports = MockClient;\n"
  },
  {
    "path": "test/lib/mocks/api-loader/assertion-loader.js",
    "content": "const common = require('../../../common.js');\nconst AssertionLoader = common.require('api-loader/assertion-loader.js');\nconst AssertionRunner = common.require('api-loader/assertion-runner.js');\nconst NightwatchError = common.require('core/assertion.js').AssertionError;\n\nmodule.exports = function(commandName, assertionModule, assertCallback, done) {\n  const originalRun = AssertionLoader.runAssertion;\n\n  AssertionLoader.runAssertion = function(instance, opts) {\n    const assertionRun = new AssertionRunnerMock(instance, opts);\n\n    assertionRun.executeCommand();\n\n    assertionRun.deferred.promise\n      .then(() => done())\n      .catch(err => done(err))\n      .then(_ => {\n        AssertionLoader.runAssertion = originalRun;\n      });\n  };\n\n  class AssertionRunnerMock extends AssertionRunner {\n    assert() {\n      return super.assert()\n        .then(() => {\n          return assertCallback.call(this, this.assertion.passed, this.assertion.actual, this.assertion.calleeFn, this.assertion.message);\n        })\n        .catch(err => {\n          if (err instanceof NightwatchError) {\n            return assertCallback.call(this, this.assertion.passed, this.assertion.actual, this.assertion.calleeFn, this.assertion.message);\n          }\n\n          this.deferred.reject(err);\n        });\n    }\n  }\n\n  class AssertionLoaderMock extends AssertionLoader {\n    loadModule(dirpath, filename) {\n      this.commandName = commandName;\n      this.__module = assertionModule;\n\n      return this;\n    }\n\n    updateElementSelector(args) {\n      return Promise.resolve();\n    }\n  }\n\n  return AssertionLoaderMock;\n};"
  },
  {
    "path": "test/lib/mocks/api-loader/assertion.js",
    "content": "const common = require('../../../common.js');\nconst AssertionLoader = common.require('api-loader/assertion.js');\nconst NightwatchError = common.require('core/assertion.js').AssertionError;\n\nmodule.exports = function(commandName, assertionModule, assertCallback, done) {\n\n  class AssertionLoaderMock extends AssertionLoader {\n    loadModule(dirpath, filename) {\n      this.commandName = commandName;\n      this.__module = assertionModule;\n\n      return this;\n    }\n\n    runAssertion() {\n      return super.runAssertion()\n        .then(() => {\n          return assertCallback.call(this, this.assertion.passed, this.assertion.actual, this.assertion.calleeFn, this.assertion.message);\n        })\n        .catch(err => {\n          if (err instanceof NightwatchError) {\n            return assertCallback.call(this, this.assertion.passed, this.assertion.actual, this.assertion.calleeFn, this.assertion.message);\n          }\n\n          throw err;\n        })\n        .then(() => done())\n        .catch(err => done(err));\n    }\n  }\n\n  return AssertionLoaderMock;\n};"
  },
  {
    "path": "test/lib/mocks/assertionLoader.js",
    "content": "const common = require('../../common.js');\nconst MockClient = require('../mockclient.js');\n\nclass AssertionLoaderMock {\n  constructor(assertionModule, commandName, settings, mockReporter = {}) {\n    this.assertionModule = common.require(assertionModule);\n    this.settings = settings;\n    this.commandName = commandName;\n    this.client = new MockClient(settings, mockReporter);\n  }\n\n  /**\n   * --\n   * getText: function (cssSelector, callback) {\n   *   callback({value: returnValue});\n   * }\n   * --\n   *\n   * @param {string} name\n   * @param {function} fn\n   */\n  setApiMethod(name, fn) {\n    this.client.api[name] = fn;\n\n    return this;\n  }\n\n  /**\n   * function (commandName, command, context, args, stackTrace) {}\n   *\n   * @param {function} fn\n   */\n  setAddToQueueFn(fn) {\n    this.client.addToQueueFn = fn;\n\n    return this;\n  }\n\n  /**\n   *\n   * @param {function} assertCallback\n   * @param {function} doneCallback\n   */\n  loadAssertion(assertCallback, doneCallback) {\n    const AssertionLoader = common.requireMock('api/_loaders/assertion.js', this.commandName, this.assertionModule, assertCallback, doneCallback);\n    let loader = new AssertionLoader(this.client);\n\n    loader.loadModule()\n      .setNamespace('assert')\n      .createWrapper(true)\n      .define();\n\n    return loader;\n  }\n\n  static create(module, commandName, settings = {}) {\n    const mockReporter = {\n      registerPassed(message) {\n      },\n      logFailedAssertion(error) {\n      },\n      registerFailed() {\n      },\n      logAssertResult(test) {\n      }\n    };\n\n    let loader = new AssertionLoaderMock(module, commandName, settings, mockReporter);\n\n    loader.setAddToQueueFn(function({commandName, commandFn, context, args, stackTrace}) {\n      commandFn.call(context, {args, stackTrace});\n    });\n\n    return loader;\n  }\n}\n\nmodule.exports = AssertionLoaderMock;\n"
  },
  {
    "path": "test/lib/mocks/core/assertion.js",
    "content": "const common = require('../../../common.js');\n\nmodule.exports = function(assertCallback) {\n\n  const NightwatchAssertion = common.require('core/assertion.js');\n\n  class NightwatchAssertionMock extends NightwatchAssertion {\n    runAssertion(passed, value, calleeFn, message) {\n      super.assert(passed, value, calleeFn, message);\n\n      assertCallback.call(this, passed, value, calleeFn, message);\n    }\n  }\n\n  return NightwatchAssertionMock;\n};"
  },
  {
    "path": "test/lib/mocks/core/session.js",
    "content": "const common = require('../../../common.js');\nconst Session = common.require('core/session.js');\n\nclass MockSession extends Session {\n  getSessionId() {\n    return '1352110219202';\n  }\n\n  get commandQueue() {\n    return {\n      add({commandName, commandFn, context, args, stackTrace}) {\n        commandFn({args, stackTrace});\n      },\n\n      empty() {\n        return this;\n      },\n\n      reset() {\n        return this;\n      }\n    };\n  }\n}\n\nmodule.exports = MockSession;\n"
  },
  {
    "path": "test/lib/mocks/mocks-jsonwire.yaml",
    "content": "---\nmocks:\n# Default JSON Wire session request with Selenium\n- url: '/wd/hub/session'\n  postdata:\n    capabilities:\n      firstMatch: [{}]\n      alwaysMatch:\n        browserName: firefox\n        'moz:firefoxOptions':\n          prefs:\n            'remote.active-protocols': 3\n  response:\n    status: 0\n    sessionId: &sessionId '1352110219202'\n    value:\n      browserName: firefox\n      browserVersion: TEST_firefox\n    state:\n  responseHeaders: {}\n  statusCode: 201\n  method: POST\n  matchEmpty: false\n\n- url: '/wd/hub/session'\n  postdata:\n    capabilities:\n      firstMatch: [{}]\n      alwaysMatch:\n        browserName: firefox\n  response:\n    status: 0\n    sessionId: &sessionId '1352110219202'\n    value:\n      browserName: firefox\n      browserVersion: TEST_firefox\n    state:\n  responseHeaders: {}\n  statusCode: 201\n  method: POST\n  matchEmpty: true\n\n- url: '/wd/hub/session/1352110219202'\n  method: DELETE\n  response:\n    status: 0\n    state: success\n\n- url: '/wd/hub/session/1352110219202/url'\n  postdata:\n    url: http://localhost\n  response:\n    status: 0\n\n- url: '/wd/hub/session/1352110219202/url'\n  postdata:\n    url: http://localhost/test_url\n  response:\n    status: 0\n\n- url: '/wd/hub/session/1352110219202/url'\n  postdata:\n    url: http://localhost/homepage\n  response:\n    status: 0\n\n- url: '/wd/hub/session/1352110219202/url'\n  method: GET\n  response:\n    status: 0\n    value: http://localhost\n\n- url: '/wd/hub/test'\n  response:\n    status: 0\n\n- url: '/wd/hub/test_error'\n  response:\n    status: 7\n    value:\n      screen: screenshot_data\n  statusCode: 500\n\n- url: '/wd/hub/session/1352110219202/element'\n  postdata:\n    using: 'css selector'\n    value: '#weblogin'\n  response:\n    sessionId: '1352110219202'\n    status: 0\n    value:\n      ELEMENT: '0'\n    class: org.openqa.selenium.remote.Response\n    hCode: 604376696\n\n- url: '/wd/hub/session/1352110219202/element'\n  postdata:\n    using: 'css selector'\n    value: '#signupSection'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value:\n      ELEMENT: '0'\n\n- url: '/wd/hub/session/1352110219202/element'\n  postdata:\n    using: xpath\n    value: '//weblogin'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value:\n      ELEMENT: '0'\n\n- url: '/wd/hub/session/1352110219202/element/0/element'\n  postdata:\n    using: 'css selector'\n    value: '#helpBtn'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value:\n      ELEMENT: '1'\n\n- url: '/wd/hub/session/1352110219202/elements'\n  postdata:\n    using: 'css selector'\n    value: '.weblogin'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value: []\n\n- url: '/wd/hub/session/1352110219202/elements'\n  postdata:\n    using: 'css selector'\n    value: '#badElement'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value: []\n\n- url: '/wd/hub/session/1352110219202/elements'\n  postdata:\n    using: 'css selector'\n    value: '#weblogin'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value:\n    - ELEMENT: '0'\n\n- url: '/wd/hub/session/1352110219202/elements'\n  postdata:\n    using: 'css selector'\n    value: '#weblogin-multiple'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value:\n    - ELEMENT: '0'\n    - ELEMENT: '1'\n\n- url: '/wd/hub/session/1352110219202/elements'\n  postdata:\n    using: xpath\n    value: '//weblogin'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value:\n    - ELEMENT: '0'\n\n- url: '/wd/hub/session/1352110219202/elements'\n  postdata:\n    using: 'css selector'\n    value: '#signupSection'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value:\n    - ELEMENT: '0'\n\n- url: '/wd/hub/session/1352110219202/element/0/elements'\n  postdata:\n    using: 'css selector'\n    value: '#helpBtn'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value:\n    - ELEMENT: '1'\n\n- url: '/wd/hub/session/1352110219202/element/0/elements'\n  postdata:\n    using: 'css selector'\n    value: '.btn'\n  response:\n    sessionId: *sessionId\n    status: 0\n    value:\n    - ELEMENT: '1'\n    - ELEMENT: '2'\n    - ELEMENT: '3'\n\n- url: '/wd/hub/session/1352110219202/buttondown'\n  postdata:\n    button: 0\n  response:\n    sessionId: *sessionId\n    status: 0\n\n- url: '/wd/hub/session/1352110219202/window'\n  response:\n    sessionId: *sessionId\n    status: 0\n  method: DELETE\n\n- url: '/wd/hub/session/1352110219202/window'\n  method: POST\n  response:\n    sessionId: *sessionId\n    status: 0\n\n- url: '/wd/hub/session/1352110219202/buttondown'\n  postdata:\n    button: 1\n  response:\n    sessionId: *sessionId\n    status: 0\n\n- url: '/wd/hub/session/1352110219202/buttonup'\n  postdata:\n    button: 2\n  response:\n    sessionId: *sessionId\n    status: 0\n\n- url: '/wd/hub/session/1352110219202/se/log'\n  postdata:\n    type: 'browser'\n  method: POST\n  response:\n    sessionId: *sessionId\n    status: 0\n    value:\n    - level: 'info'\n      timestamp: 534547832\n      message: 'Test log'\n    - level: 'info'\n      timestamp: 534547442\n      message: 'Test log2'\n"
  },
  {
    "path": "test/lib/mocks/mocks-w3c.yaml",
    "content": "---\nmocks:\n#\n# Webdriver session request without Selenium\n# -------------------------------------------------------\n- url: '/session'\n  postdata:\n    capabilities:\n      firstMatch: [{}]\n      alwaysMatch:\n        browserName: firefox\n        'moz:firefoxOptions':\n          prefs:\n            'remote.active-protocols': 3\n  response:\n    value:\n      sessionId: &webdriverSessionId '13521-10219-202'\n      capabilities:\n        acceptInsecureCerts: false\n        browserName: firefox\n        browserVersion: 65.0.1\n        platformName: linux\n        platformVersion: 4.9.125-linuxkit\n        setWindowRect: true\n        strictFileInteractability: false\n        timeouts:\n          implicit: 0\n          pageLoad: 300000\n          script: 30000\n        unhandledPromptBehavior: 'dismiss and notify'\n  responseHeaders: {}\n  statusCode: 201\n  method: POST\n\n- url: '/session'\n  postdata:\n    capabilities:\n      firstMatch: [{}]\n      alwaysMatch:\n        browserName: firefox\n  response:\n    value:\n      sessionId: '13521-10219-202'\n      capabilities:\n        acceptInsecureCerts: false\n        browserName: firefox\n        browserVersion: 65.0.1\n        platformName: linux\n        platformVersion: 4.9.125-linuxkit\n        setWindowRect: true\n        strictFileInteractability: false\n        timeouts:\n          implicit: 0\n          pageLoad: 300000\n          script: 30000\n        unhandledPromptBehavior: 'dismiss and notify'\n  responseHeaders: {}\n  statusCode: 201\n  method: POST\n\n- url: '/session'\n  postdata:\n    capabilities:\n      firstMatch: [{}]\n      alwaysMatch:\n        browserName: firefox\n  response:\n    value:\n      sessionId: '13521-10219-202'\n      capabilities:\n        browserName: firefox\n        browserVersion: 65.0.1\n        platformName: linux\n        platformVersion: 4.9.125-linuxkit\n  responseHeaders: {}\n  statusCode: 201\n  method: POST\n\n- url: '/session'\n  postdata:\n    desiredCapabilities:\n      browserName: safari\n      platformName: iOS\n      safari:useSimulator: true\n      safari.options: {}\n    capabilities:\n      alwaysMatch:\n        browserName: safari\n        platformName: iOS\n        safari:useSimulator: true\n  response:\n    value:\n      sessionId: '13521-10219-202'\n      capabilities:\n        browserName: safari\n        platformName: iOS\n        safari:useSimulator: true\n        safari:platformVersion: 15.6.1\n  responseHeaders: {}\n  statusCode: 201\n  method: POST\n\n- url: '/wd/hub/session'\n  postdata:\n    capabilities:\n      firstMatch: [{}]\n      alwaysMatch:\n        appium:automationName: \"XCUITest\"\n        appium:appPackage: \"org.wikimedia.wikipedia\"\n        platformName: \"iOS\"\n        appium:deviceName: \"iPhone 13\"\n        appium:platformVersion: \"15.5\"\n  response:\n    value:\n      sessionId: '13521-10219-202'\n      capabilities:\n        appium:automationName: \"XCUITest\"\n        appium:appPackage: \"org.wikimedia.wikipedia\"\n        platformName: \"iOS\"\n        appium:deviceName: \"iPhone 13\"\n        appium:platformVersion: \"15.5\"\n  responseHeaders: {}\n  statusCode: 201\n  method: POST\n\n- url: '/wd/hub/session/1352110219202/element'\n  postdata:\n    using: 'css selector'\n    value: '#webdriver'\n  response:\n    sessionId: '1352110219202'\n    status: 0\n    value:\n      element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b\n\n- url: '/session/13521-10219-202/element'\n  postdata:\n    using: 'css selector'\n    value: '#webdriver'\n  response:\n    value:\n      element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b\n\n- url: '/wd/hub/session/1352110219202/elements'\n  postdata:\n    using: 'css selector'\n    value: '#webdriver'\n  response:\n    sessionId: '1352110219202'\n    status: 0\n    value:\n    - element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b\n\n- url: '/session/13521-10219-202/elements'\n  postdata:\n    using: 'css selector'\n    value: '#webdriver'\n  response:\n    value:\n    - element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b\n    - element-6066-11e4-a52e-4f735466cecf: 3783b042-7001-0740-a2c0-afdaac732e9f\n\n- url: '/session/13521-10219-202/elements'\n  postdata:\n    using: 'css selector'\n    value: '#weblogin'\n  response: \n    value: \n    - element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b\n    - element-6066-11e4-a52e-4f735466cecf: 3783b042-7001-0740-a2c0-afdaac732e9f\n\n- url: '/session/13521-10219-202/elements'\n  postdata:\n    using: 'xpath'\n    value: '//weblogin'\n  response: \n    value: \n    - element-6066-11e4-a52e-4f735466cecf: 5cc459b8-36a8-3042-8b4a-258883ea642b\n    - element-6066-11e4-a52e-4f735466cecf: 3783b042-7001-0740-a2c0-afdaac732e9f\n\n- url: '/session/13521-10219-202/elements'\n  postdata:\n    using: 'css selector'\n    value: 'html'\n  response:\n    value:\n    - element-6066-11e4-a52e-4f735466cecf: '00'\n\n- url: '/session/13521-10219-202/element/00/elements'\n  postdata:\n    using: 'css selector'\n    value: '#signupSection'\n  response:\n    value:\n    - element-6066-11e4-a52e-4f735466cecf: '0'\n\n- url: '/session/13521-10219-202/elements'\n  postdata:\n    using: 'css selector'\n    value: '#signupSection'\n  response:\n    value:\n    - element-6066-11e4-a52e-4f735466cecf: '0'\n\n- url: '/session/13521-10219-202/element/0/elements'\n  postdata:\n    using: 'css selector'\n    value: '#helpBtn'\n  response:\n    value:\n    - element-6066-11e4-a52e-4f735466cecf: '1'\n\n- url: '/session/13521-10219-202/element/0/elements'\n  postdata:\n    using: 'css selector'\n    value: '.btn'\n  response:\n    value:\n    - element-6066-11e4-a52e-4f735466cecf: '1'\n    - element-6066-11e4-a52e-4f735466cecf: '2'\n    - element-6066-11e4-a52e-4f735466cecf: '3'\n"
  },
  {
    "path": "test/lib/mocks.json",
    "content": "{\n  \"mocks\": [\n    {\n      \"url\": \"/wd/hub/session\",\n      \"postdata\": {\n        \"desiredCapabilities\": {\n          \"browserName\": \"firefox\"\n        }\n      },\n      \"response\": {\n        \"status\": 0,\n        \"sessionId\": \"1352110219202\",\n        \"value\": {\n          \"browserName\": \"firefox\",\n          \"browserVersion\": \"TEST\",\n          \"platformVersion\": \"TEST\"\n        },\n        \"state\": null\n      },\n      \"responseHeaders\": {\n      },\n      \"statusCode\": 201,\n      \"method\": \"POST\"\n    },\n\n    {\n      \"url\": \"/session\",\n      \"postdata\": {\n        \"capabilities\": {\n          \"browserName\": \"firefox\"\n        },\n        \"desiredCapabilities\": {\n          \"browserName\": \"firefox\"\n        }\n      },\n\n      \"response\": {\n        \"value\": {\n          \"sessionId\": \"13521-10219-202\",\n          \"capabilities\": {\n            \"acceptInsecureCerts\": false,\n            \"browserName\": \"firefox\",\n            \"browserVersion\": \"65.0.1\",\n            \"platformName\": \"linux\",\n            \"platformVersion\": \"4.9.125-linuxkit\",\n            \"setWindowRect\": true,\n            \"strictFileInteractability\": false,\n            \"timeouts\": {\n              \"implicit\": 0,\n              \"pageLoad\": 300000,\n              \"script\": 30000\n            },\n            \"unhandledPromptBehavior\": \"dismiss and notify\"\n          }\n        }\n      },\n      \"responseHeaders\": {\n      },\n      \"statusCode\": 201,\n      \"method\": \"POST\"\n    },\n\n    {\n      \"url\": \"/wd/hub/session\",\n      \"postdata\": \"\",\n      \"response\": {\n        \"status\": 0,\n        \"sessionId\": \"1352110219202\",\n        \"value\": {\n          \"browserName\": \"firefox\",\n          \"version\": \"TEST\",\n          \"platform\": \"TEST\"\n        },\n        \"state\": null\n      },\n      \"responseHeaders\": {\n      },\n      \"statusCode\": 201,\n      \"method\": \"POST\"\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202\",\n      \"method\": \"DELETE\",\n      \"response\": {\n        \"status\": 0,\n        \"state\": \"success\"\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/url\",\n      \"postdata\": {\n        \"url\": \"http://localhost\"\n      }\n    },\n    {\n      \"url\": \"/wd/hub/test\",\n      \"response\": {\n        \"status\": 0\n      }\n    },\n    {\n      \"url\": \"/wd/hub/test_error\",\n      \"response\": {\n        \"status\": 7,\n        \"value\": {\n          \"screen\": \"screenshot_data\"\n        }\n      },\n      \"statusCode\": 500\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/element\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#weblogin\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": {\n          \"ELEMENT\": \"0\"\n        },\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/element\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#webdriver\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": {\n          \"element-6066-11e4-a52e-4f735466cecf\": \"5cc459b8-36a8-3042-8b4a-258883ea642b\"\n        }\n      }\n    },\n    {\n      \"url\": \"/session/13521-10219-202/element\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#webdriver\"\n      },\n      \"response\": {\n        \"value\": {\n          \"element-6066-11e4-a52e-4f735466cecf\": \"5cc459b8-36a8-3042-8b4a-258883ea642b\"\n        }\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/element\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#signupSection\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": {\n          \"ELEMENT\": \"0\"\n        },\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/element\",\n      \"postdata\": {\n        \"using\": \"xpath\",\n        \"value\": \"//weblogin\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": {\n          \"ELEMENT\": \"0\"\n        },\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n\n    {\n      \"url\": \"/wd/hub/session/1352110219202/element/0/element\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#helpBtn\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": {\n          \"ELEMENT\": \"1\"\n        },\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/elements\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \".weblogin\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": [],\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/elements\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#badElement\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": [],\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/elements\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#weblogin\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": [\n          {\n            \"ELEMENT\": \"0\"\n          }\n        ],\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/elements\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#webdriver\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": [\n          {\n            \"element-6066-11e4-a52e-4f735466cecf\": \"5cc459b8-36a8-3042-8b4a-258883ea642b\"\n          }\n        ]\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/elements\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#weblogin-multiple\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": [\n          {\n            \"ELEMENT\": \"0\"\n          },\n          {\n            \"ELEMENT\": \"1\"\n          }\n        ],\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/elements\",\n      \"postdata\": {\n        \"using\": \"xpath\",\n        \"value\": \"//weblogin\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": [\n          {\n            \"ELEMENT\": \"0\"\n          }\n        ],\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/elements\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#signupSection\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": [\n          {\n            \"ELEMENT\": \"0\"\n          },\n          {\n            \"ELEMENT\": \"1\"\n          }\n        ],\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/element/0/elements\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \"#helpBtn\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": [\n          {\n            \"ELEMENT\": \"1\"\n          }\n        ],\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/element/0/elements\",\n      \"postdata\": {\n        \"using\": \"css selector\",\n        \"value\": \".btn\"\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"value\": [\n          {\n            \"ELEMENT\": \"1\"\n          },\n          {\n            \"ELEMENT\": \"2\"\n          },\n          {\n            \"ELEMENT\": \"3\"\n          }\n        ],\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/buttondown\",\n      \"postdata\": {\n        \"button\": 0\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/window\",\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0\n      },\n      \"method\": \"DELETE\"\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/window\",\n      \"method\": \"POST\",\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/buttondown\",\n      \"postdata\": {\n        \"button\": 1\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    },\n    {\n      \"url\": \"/wd/hub/session/1352110219202/buttonup\",\n      \"postdata\": {\n        \"button\": 2\n      },\n      \"response\": {\n        \"sessionId\": \"1352110219202\",\n        \"status\": 0,\n        \"class\": \"org.openqa.selenium.remote.Response\",\n        \"hCode\": 604376696\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "test/lib/mockserver.js",
    "content": "const http = require('http');\nconst jsYaml = require('js-yaml');\nconst fs   = require('fs');\nconst path   = require('path');\nconst defaultsDeep = require('lodash/defaultsDeep');\n\nclass MockServer {\n\n  static get defaultOptions() {\n    return {\n      postdata: '',\n      weakURLVerification: false,\n      responseHeaders: {},\n      contentType: 'application/json',\n      mocks: [],\n      finishedCallback() {}\n    };\n  }\n\n  get options() {\n    return this.__options;\n  }\n\n  get mocks() {\n    return this.__mocks;\n  }\n\n  constructor(opts = {}, callback = function () {}) {\n    this.__options = opts;\n    defaultsDeep(this.__options, MockServer.defaultOptions);\n    this.__mocks = this.options.mocks;\n    this.cb = callback;\n\n    this.createServer();\n  }\n\n  listen() {\n    this.server.listen(this.options.port, this.cb);\n\n    return this.server;\n  }\n\n  createServer() {\n    this.server = http.createServer((req, res) => {\n      let postdata = '';\n      let headers;\n      req.setEncoding('utf8');\n      req.on('data', function(chunk) {\n        postdata += chunk;\n      });\n\n      req.on('end', () => {\n        const item = this.nextInLine(req, postdata);\n        let responsedata = '';\n\n        if (item) {\n          headers = item.responseHeaders;\n          responsedata = JSON.stringify(item.response);\n          headers['Content-Type']   = item.contentType || this.options.contentType;\n          headers['Content-Length'] = responsedata.length;\n          res.writeHead(Number(item.statusCode), headers);\n\n          if (item.onRequest) {\n            let requestData = '';\n            try {\n              requestData = JSON.parse(postdata);\n              // eslint-disable-next-line no-empty\n            } catch (e) {}\n\n            item.onRequest(item, requestData);\n          }\n\n          if (item.onResponse) {\n            item.onResponse();\n          }\n\n          if (item.__once) {\n            this.removeMock(item);\n          }\n        } else {\n          headers = {};\n          headers['Content-Type'] = 'text/plain';\n          headers['Content-Length'] = 0;\n          res.writeHead(404, 'Not Found', headers);\n        }\n\n        this.options.finishedCallback(req, res);\n\n        if (item && item.socketDelay) {\n          const timeoutId = setTimeout(function() {\n            res.end(responsedata);\n          }, item.socketDelay);\n\n          req.on('close', function(err) {\n            clearTimeout(timeoutId);\n          });\n\n          return;\n        }\n\n        res.end(responsedata);\n      });\n    });\n  }\n\n  /**\n   * @param {} item\n   * @param {boolean} once\n   */\n  addMock(item, once = false) {\n    let {times = 0} = item;\n\n    if (once || times >= 1) {\n      item.__once = true;\n    }\n\n    if (!times) {\n      times = 1;\n    }\n\n    // if (item.response && typeof item.response == 'string') {\n    //   item.response = JSON.parse(item.response);\n    // }\n\n    if (item.response && typeof item.response == 'string') {\n      item.contentType = item.contentType || 'application/json';\n\n      if (item.contentType === 'application/json') {\n        try {\n          item.response = JSON.parse(item.response);\n        } catch (err) {\n          console.warn('Invalid json supplied as response:', item.response);\n        }\n      }\n    }\n\n    for (let i = 0; i < times; i++) {\n      this.mocks.push(item);\n    }\n\n  }\n\n  removeMock(mock) {\n    const normalizedPostData = mock.postdata && normalizeJSONString(mock.postdata);\n    const mockMethod = mock.method || 'get';\n\n    for (let i = 0; i < this.mocks.length; i++) {\n      const item = this.mocks[i];\n\n      if (\n        item.url === mock.url && item.method.toLowerCase() === mockMethod.toLowerCase() &&\n        (!mock.postdata || isPostDataEqual(item.postdata, normalizedPostData, item.matchEmpty))\n      ) {\n        this.mocks.splice(i, 1);\n        break;\n      }\n    }\n  }\n\n  nextInLine(req, postdata) {\n    const data = postdata ? normalizeJSONString(postdata) : null;\n\n    for (let i = 0; i < this.mocks.length; i++) {\n      const item = this.mocks[i];\n\n      item.postdata = item.postdata || '';\n      item.method = item.method || 'POST';\n      item.statusCode = item.statusCode || 200;\n\n      if (item.url === req.url && item.method.toLowerCase() === req.method.toLowerCase()) {\n        item.responseHeaders = item.responseHeaders || {};\n        item.response = item.response || '';\n\n        if (!item.postdata) {\n          return item;\n        }\n\n        if (data && isPostDataEqual(item.postdata, data, item.matchEmpty)) {\n          return item;\n        }\n\n        if (!data) {\n          return item;\n        }\n      }\n    }\n\n    return null;\n  }\n\n}\n\nconst isPostDataEqual = (notNormalizedData, normalizedData, matchEmpty = false) => {\n  let normalized;\n\n  if (typeof notNormalizedData == 'string') {\n    normalized = normalizeJSONString(notNormalizedData);\n  } else if (typeof notNormalizedData == 'object') {\n    normalized = JSON.stringify(notNormalizedData);\n  }\n\n  const postDataEquals = normalizedData === normalized;\n  if (matchEmpty && !postDataEquals) {\n    const incomingPostData = JSON.parse(normalized);\n    const matchData = JSON.parse(normalizedData);\n\n    return objectIncludes(matchData, incomingPostData);\n  }\n\n  return postDataEquals;\n};\n\nconst objectIncludes = (target, source) => {\n  return Object.keys(target).every(function(key) {\n    if (!(key in source)) {\n      return false;\n    }\n\n    if (source[key] && typeof source[key] == 'object') {\n      return objectIncludes(target[key], source[key]);\n    }\n\n    return (target[key] === source[key] || source[key] === '');\n  });\n};\n\nconst normalizeJSONString = (data) => {\n  try {\n    if (typeof data == 'string') {\n      return JSON.stringify(JSON.parse(data));\n    }\n\n    return JSON.stringify(data);\n  } catch (err) {\n    console.error('Unabled to parse: \"', data, '\"');\n    console.error(err);\n  }\n};\n\nlet server;\n\nmodule.exports = {\n  init(callback = function() {}, {port = 10195} = {}) {\n    Object.keys(require.cache).forEach(function(module) {\n      if (module.indexOf('/mocks.json') > -1) {\n        delete require.cache[module];\n      }\n    });\n\n    const mockObjectsJsonWire = jsYaml.safeLoad(\n      fs.readFileSync(path.join(__dirname, './mocks/mocks-jsonwire.yaml'), 'utf8')\n    );\n    const mockObjectsW3C = jsYaml.safeLoad(\n      fs.readFileSync(path.join(__dirname, './mocks/mocks-w3c.yaml'), 'utf8')\n    );\n\n    const mocks = mockObjectsJsonWire.mocks.concat(mockObjectsW3C.mocks);\n\n    server = new MockServer({\n      port,\n      mocks\n    }, callback);\n\n    try {\n      return server.listen();\n    } catch (err) {\n      console.error(err);\n      process.exit(1);\n    }\n  },\n\n  initAsync({port, mocks = []} = {}) {\n    return new Promise(function(resolve, reject) {\n      server = new MockServer({\n        port,\n        mocks\n      }, function() {});\n      const httpServer = server.listen();\n      httpServer.on('listening', function () {\n        resolve(server);\n      });\n    });\n  },\n\n  /**\n   *\n   * @param {Object} item\n   * @param {boolean} once\n   */\n  addMock(item, once, twice) {\n    if (!server) {\n      throw new Error('Server is not yet created');\n    }\n    server.addMock(item, once);\n    if (twice) {\n      server.addMock(item, once);\n    }\n\n    return this;\n  },\n\n  /**\n   *\n   * @param {Object} mock\n   */\n  removeMock(mock) {\n    return server.removeMock(mock);\n  }\n};\n"
  },
  {
    "path": "test/lib/nightwatch.js",
    "content": "const lodashMerge = require('lodash/merge');\nconst MockServer  = require('./mockserver.js');\nconst common = require('../common.js');\nconst Settings = common.require('settings/settings.js');\nconst {Logger} = common.require('utils');\nconst Nightwatch = common.require('index.js');\n\nmodule.exports = new function () {\n  let _client = null;\n  let _mockServer = null;\n\n  //Logger.setOutputEnabled(process.env.VERBOSE === '1' || false);\n  Logger.setOutputEnabled(true);\n  Logger.enable();\n\n  this.startMockServer = function (done = function() {}) {\n    return new Promise((resolve) => {\n      _mockServer = MockServer.init();\n      _mockServer.on('listening', () => {\n        done();\n        resolve();\n      });\n    });\n  };\n\n  const stopMockServer = (done) => {\n    if (!_mockServer) {\n      return Promise.resolve();\n    }\n\n    _mockServer.close(function() {\n      done();\n    });\n  };\n\n  function extendClient(client) {\n    client.start = function(done = function() {}) {\n      return this.queue.run().then(function(err) {\n        if (err) {\n          return done(err);\n        }\n\n        done();\n      });\n    };\n  }\n\n  this.createClient = function(options = {}, reporter = null, argv = {}) {\n    const opts = {\n      selenium: {\n        port: 10195,\n        host: 'localhost',\n        start_process: false,\n        version2: true\n      },\n      webdriver: {\n        start_process: false\n      },\n      silent: true,\n      output: false,\n      disable_colors: true,\n      globals: {\n        myGlobal: 'test'\n      }\n    };\n\n    lodashMerge(opts, options);\n\n    if (opts.output) {\n      Logger.setOutputEnabled(true);\n    }\n\n    const settings = Settings.parse(opts);\n\n    return Nightwatch.client(settings, reporter, argv);\n  };\n\n  this.createClientDefaults = function() {\n    return Nightwatch.client();\n  };\n\n  this.init = async function(options, callback = function() {}) {\n    _client = this.createClient(options);\n\n    return _client.initialize().then(() => {\n      extendClient(_client);\n\n      _client.once('nightwatch:session.create', function(id) {\n        callback();\n      }).once('nightwatch:session.error', function(err) {\n        callback(err);\n        process.exit(1);\n      });\n\n      _client.startSession();\n    });\n\n  };\n\n  this.initAsync = async function(options, reporter) {\n    _client = this.createClient(options, reporter);\n    await _client.initialize();\n\n    _client.start = function() {\n      return this.queue.run().then(err => {\n        if (err instanceof Error) {\n          throw err;\n        }\n      });\n    };\n\n    return new Promise((resolve, reject) => {\n      _client\n        .once('nightwatch:session.create', id => resolve(id))\n        .once('nightwatch:session.error', err => reject(err));\n\n      _client.createSession().catch(err => reject(err));\n    });\n  };\n\n  this.initW3CClient = function(opts = {}, argv = {}) {\n    const settings = Object.assign({\n      selenium: {\n        version2: false,\n        start_process: false,\n        host: null\n      },\n      webdriver: {\n        start_process: false,\n        host: 'localhost'\n      }\n    }, opts);\n\n    return this.initClient(settings, null, argv);\n  };\n\n  this.initClient = async function(options, reporter, argv) {\n    const client = this.createClient(options, reporter, argv);\n    await client.initialize();\n\n    extendClient(client);\n\n    return new Promise(function(resolve, reject) {\n      client.once('nightwatch:session.create', function(id) {\n        resolve(client);\n      }).once('nightwatch:session.error', function(err) {\n        reject(err);\n      });\n\n      client.startSession();\n    });\n  };\n\n  this.api = function() {\n    return _client.api;\n  };\n\n  this.client = function() {\n    return _client;\n  };\n\n  this.start = function(done) {\n    return _client.start(done);\n  };\n\n  this.stop = function(done = function() {}) {\n    stopMockServer(done);\n  };\n\n  this.addMock = function(mock, once = false) {\n    return MockServer.addMock(mock, once);\n  };\n};\n"
  },
  {
    "path": "test/lib/nocks.js",
    "content": "const nock = require('nock');\nconst ElementNocks = require('./nockselements.js');\n\nmodule.exports = {\n  disabled: false,\n  disable() {\n    this.disabled = true;\n    ElementNocks.disabled = true;\n    nock.cleanAll();\n    nock.restore();\n\n    return this;\n  },\n\n  enable(force) {\n    if (this.disabled || force) {\n      nock.activate();\n    }\n\n    return this;\n  },\n\n  createW3cSession() {\n    nock('http://localhost:10195')\n      .post('/session')\n      .reply(201, {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            acceptInsecureCerts: false,\n            browserName: 'firefox',\n            browserVersion: '65.0.1'\n          }\n        }\n      });\n\n    return this;\n  },\n  \n  createSession() {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'firefox',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    return this;\n  },\n\n  deleteW3cSession() {\n    nock('http://localhost:10195')\n      .delete('/session/13521-10219-202')\n      .reply(200);\n\n    return this;\n  },\n\n  deleteSession() {\n    nock('http://localhost:10195')\n      .delete('/wd/hub/session/1352110219202')\n      .reply(204, '');\n\n    return this;\n  },\n\n  urlW3c() {\n    nock('http://localhost:10195')\n      .post('/sesion/13521-10219-202/url')\n      .reply(200, {value: null});\n\n    return this;\n  },\n  \n  url() {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/url', {url: 'http://localhost'})\n      .reply(200, {\n        status: 0,\n        state: 'success'\n      });\n\n    return this;\n  },\n\n  getUrl(value = 'http://localhost') {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/url')\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value\n      });\n\n    return this;\n  },\n\n  getPageSource(value = '<html><body><p>404 not found</p></body></html>') {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/source')\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value\n      });\n\n    return this;\n  },\n\n  elementFoundW3c() {\n    nock('http://localhost:10195')\n      .post('/session/13521-10219-202/elements')\n      .reply(200, {\n        value: [{'element-6066-11e4-a52e-4f735466cecf': ' 5cc459b8-36a8-3042-8b4a-258883ea642b'}]\n      });\n\n    return this;\n  },\n\n  elementFound() {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/elements', {'using': 'css selector', 'value': '#weblogin'})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '0'}]\n      });\n\n    return this;\n  },\n\n  appiumElementFound() {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/elements', {'using': 'id', 'value': 'com.app:id/web-login'})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '0'}]\n      });\n\n    return this;\n  },\n\n  click() {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/element/0/click')\n      .reply(200, {\n        status: 0,\n        state: 'success'\n      });\n\n    return this;\n  },\n\n  elementStateError({error, times, code = 400, url = '/wd/hub/session/1352110219202/execute/sync', method = 'post', reply}) {\n    const mock = nock('http://localhost:10195')[method](url);\n\n    if (times) {\n      mock.times(times);\n    }\n\n    reply = reply || {\n      error,\n      message: error,\n      stacktrace: ''\n    };\n\n    mock.reply(code, reply);\n\n    return this;\n  },\n\n  elementNotFound() {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/elements', {'using': 'css selector', 'value': '#weblogin'})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: []\n      });\n\n    return this;\n  },\n\n  childElementsNotFound(selector = '#badElement') {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/element/0/elements', {'using': 'css selector', 'value': selector})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: []\n      });\n\n    return this;\n  },\n\n  childElementsFound(selector = '#weblogin') {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/element/0/elements', {'using': 'css selector', 'value': selector})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '0'}]\n      });\n\n    return this;\n  },\n\n  elementFoundXpath() {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/elements', {'using': 'xpath', 'value': '//weblogin'})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '0'}]\n      });\n\n    return this;\n  },\n\n  attributeValue(value) {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/attribute/class')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: value,\n        state: 'success'\n      });\n\n    return this;\n  },\n\n  attributeValueSync(value) {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/execute/sync')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: value,\n        state: 'success'\n      });\n\n    return this;\n  },\n\n  propertyValue(value, propertyName = 'className') {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/property/' + propertyName)\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value,\n        state: 'success'\n      });\n\n    return this;\n  },\n\n  cssProperty(value, times) {\n    var mock = nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/css/display');\n\n    if (times) {\n      mock.times(times);\n    }\n\n    mock.reply(200, {\n      status: 0,\n      sessionId: '1352110219202',\n      value: value,\n      state: 'success'\n    });\n\n    return this;\n  },\n\n  property(value, times) {\n    var mock = nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/property/display');\n\n    if (times) {\n      mock.times(times);\n    }\n\n    mock.reply(200, {\n      status: 0,\n      sessionId: '1352110219202',\n      value: value,\n      state: 'success'\n    });\n\n    return this;\n  },\n\n  enabled(times) {\n    var mock = nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/enabled');\n\n    if (times) {\n      mock.times(times);\n    }\n\n    mock.reply(200, {\n      status: 0,\n      sessionId: '1352110219202',\n      value: true,\n      state: 'success'\n    });\n\n    return this;\n  },\n\n  notEnabled(times) {\n    var mock = nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/enabled');\n\n    if (times) {\n      mock.times(times);\n    }\n\n    mock.reply(200, {\n      status: 0,\n      sessionId: '1352110219202',\n      value: false,\n      state: 'success'\n    });\n\n    return this;\n  },\n\n  selected() {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/selected')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: true,\n        state: 'success'\n      });\n\n    return this;\n  },\n\n  notSelected(times) {\n    var mock = nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/selected');\n\n    if (times) {\n      mock.times(times);\n    }\n\n    mock.reply(200, {\n      status: 0,\n      sessionId: '1352110219202',\n      value: false,\n      state: 'success'\n    });\n\n    return this;\n  },\n\n  visible() {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/execute/sync')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: true,\n        state: 'success'\n      });\n\n    return this;\n  },\n\n  appiumElementVisible() {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/displayed')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: true,\n        state: 'success'\n      });\n\n    return this;\n  },\n\n  notVisible(times) {\n    var mock = nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/execute/sync');\n\n    if (times) {\n      mock.times(times);\n    }\n\n    mock.reply(200, {\n      status: 0,\n      sessionId: '1352110219202',\n      value: false,\n      state: 'success'\n    });\n\n    return this;\n  },\n\n  value(value, times) {\n    var mock = nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/property/value');\n\n    if (times) {\n      mock.times(times);\n    }\n\n    mock.reply(200, {\n      status: 0,\n      sessionId: '1352110219202',\n      value: value,\n      state: 'success'\n    });\n\n    return this;\n  },\n\n  text(value, times) {\n    var mock = nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/text');\n\n    if (times) {\n      mock.times(times);\n    }\n\n    mock.reply(200, {\n      status: 0,\n      sessionId: '1352110219202',\n      value: value,\n      state: 'success'\n    });\n\n    return this;\n  },\n\n  name(value) {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/name')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: value,\n        state: 'success'\n      });\n\n    return this;\n  },\n\n  title(value) {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/title')\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: value\n      });\n\n    return this;\n  },\n\n  active() {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/active')\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: {'element-6066-11e4-a52e-4f735466cecf': '0'}\n      });\n\n    return this;\n  },\n\n  notActive() {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/active')\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: {'element-6066-11e4-a52e-4f735466cecf': 'other'}\n      });\n\n    return this;\n  },\n\n  height(value) {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/size')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          height: value\n        }\n      });\n\n    return this;\n  },\n\n  width(value) {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/size')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          width: value\n        }\n      });\n\n    return this;\n  },\n\n  xPosition(value) {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/location_in_view')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          x: value\n        }\n      });\n\n    return this;\n  },\n\n  yPosition(value) {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/element/0/location_in_view')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          y: value\n        }\n      });\n\n    return this;\n  },\n\n  elementsFound(selector) {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/elements', {'using': 'css selector', 'value': selector})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '0'},\n          {'element-6066-11e4-a52e-4f735466cecf': '1'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      });\n\n    return this;\n  },\n\n  elementsNotFound(selector) {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/elements', {'using': 'css selector', 'value': selector})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: []\n      });\n\n    return this;\n  },\n\n  cookie(name, value) {\n    nock('http://localhost:10195')\n      .get(`/wd/hub/session/1352110219202/cookie/${name}`)\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: {\n          domain: 'cookie-domain',\n          name: name,\n          value: value\n        }\n      });\n\n    return this;\n  },\n\n  multipleCookiesFound(value) {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/cookie')\n      .reply(200, {\n        value\n      });\n\n    return this;\n  },\n\n  cookieNotFound() {\n    nock('http://localhost:10195')\n      .get('/wd/hub/session/1352110219202/cookie')\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: []\n      });\n\n    return this;\n  },\n\n  analyticsCollector(GAPath) {\n    return nock('https://localhost:13555')\n      .post(GAPath)\n      .reply(204, {\n        status: 0,\n        state: 'success',\n        value: []\n      });\n  },\n\n  cleanAll() {\n    nock.cleanAll();\n\n    return this;\n  }\n};\n"
  },
  {
    "path": "test/lib/nockselements.js",
    "content": "const nock = require('nock');\n\n/**\n * More granular nocks definitions for element apis\n */\nmodule.exports = {\n  _currentNocks: [],\n  _requestUri: 'http://localhost:10195',\n  _protocolUri: '/wd/hub/session/1352110219202/',\n\n  _addNock(...args) {\n    let item = nock(...args);\n\n    this._currentNocks.push(item);\n\n    return item;\n  },\n\n  createSession() {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'firefox',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    return this;\n  },\n\n  checkIfMocksDone() {\n    try {\n      this._currentNocks.forEach(nock => nock.done());\n    } catch (err) {\n      return err;\n    }\n  },\n\n  elementFound(selector = '#nock', using = 'css selector', foundElem = {ELEMENT: '0'}) {\n    this._addNock(this._requestUri)\n      .persist()\n      .post(this._protocolUri + 'element', {using: using, value: selector})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: foundElem\n      });\n\n    return this;\n  },\n\n  elementsFound(selector, foundArray, using) {\n    this._addNock(this._requestUri)\n      .persist()\n      .post(this._protocolUri + 'elements', {'using': using || 'css selector', 'value': selector || '.nock'})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: foundArray || [{ELEMENT: '0'}, {ELEMENT: '1'}, {ELEMENT: '2'}]\n      });\n\n    return this;\n  },\n\n  elementNotFound(selector = '#nock-none') {\n    this._addNock(this._requestUri)\n      .persist()\n      .post(this._protocolUri + 'element',\n        {\n          using: 'css selector',\n          value: selector\n        })\n      .reply(200, {\n        status: -1,\n        value: {},\n        errorStatus: 7,\n        error: 'An element could not be located on the page using the given search parameters.'\n      });\n\n    return this;\n  },\n\n  elementsNotFound(selector) {\n    this._addNock(this._requestUri)\n      .persist()\n      .post(this._protocolUri + 'elements', {'using': 'css selector', 'value': selector || '.nock-none'})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: []\n      });\n\n    return this;\n  },\n\n  elementByXpath(selector, foundElem) {\n    this._addNock(this._requestUri)\n      .persist()\n      .post(this._protocolUri + 'element', {'using': 'xpath', 'value': selector || '//[@id=\"nock\"]'})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: foundElem || {ELEMENT: '0'}\n      });\n\n    return this;\n  },\n\n  elementsByXpath(selector = '//[@class=\"nock\"]', foundArray = [{ELEMENT: '0'}, {ELEMENT: '1'}, {ELEMENT: '2'}]) {\n    this._addNock(this._requestUri)\n      .persist()\n      .post(this._protocolUri + 'elements', {'using': 'xpath', 'value': selector})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: foundArray\n      });\n\n    return this;\n  },\n\n  elementsByXpathError(selector = '.nock') {\n    this._addNock(this._requestUri)\n      .post(this._protocolUri + 'elements', {using: 'xpath', value: selector})\n      .reply(500, {\n        status: 19,\n        state: 'XPathLookupError',\n        value: null\n      });\n\n    return this;\n  },\n\n  elementId (id, selector, using, foundElem) {\n    this._addNock(this._requestUri)\n      .persist()\n      .post(this._protocolUri + 'element/' + (id || 0) + '/element',\n        {'using': using || 'css selector', 'value': selector || '#nock'})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: foundElem || {ELEMENT: '0'}\n      });\n\n    return this;\n  },\n\n  elementsId(id = 0, selector = '.nock', foundArray = [{ELEMENT: '0'}, {ELEMENT: '1'}, {ELEMENT: '2'}], using = 'css selector') {\n    this._addNock(this._requestUri)\n      .persist()\n      .post(this._protocolUri + 'element/' + id + '/elements', {\n        using: using,\n        value: selector\n      })\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: foundArray\n      });\n\n    return this;\n  },\n\n  elementIdNotFound (id, selector, using) {\n    this._addNock(this._requestUri)\n      .persist()\n      .post(this._protocolUri + 'element/' + (id || 0) + '/element',\n        {'using': using || 'css selector', 'value': selector || '#nock'})\n      .reply(200, {\n        status: -1,\n        value: {},\n        errorStatus: 7,\n        error: 'An element could not be located on the page using the given search parameters.'\n      });\n\n    return this;\n  },\n\n  elementsByTag(selector, foundArray) {\n    this._addNock(this._requestUri)\n      .persist()\n      .post(this._protocolUri + 'elements', {'using': 'css selector', 'value': selector || 'nock'})\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: foundArray || [{ELEMENT: '0'}, {ELEMENT: '1'}, {ELEMENT: '2'}]\n      });\n\n    return this;\n  },\n\n  text(id, value) {\n    this._addNock(this._requestUri)\n      .persist()\n      .get(this._protocolUri + 'element/' + (id || 0) + '/text')\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: value || 'textValue'\n      });\n\n    return this;\n  },\n\n  clearValue(id, persist = false) {\n    const mock = this._addNock(this._requestUri);\n    if (persist) {\n      mock.persist();\n    }\n\n    mock\n      .post(this._protocolUri + 'element/' + (id || 0) + '/clear')\n      .reply(200, {\n        status: 0,\n        state: 'success',\n        value: null\n      });\n\n    return this;\n  },\n\n  cleanAll () {\n    nock.cleanAll();\n    this._currentNocks = [];\n\n    return this;\n  },\n\n  disabled: false,\n  disable() {\n    this.disabled = true;\n    nock.restore();\n\n    return this;\n  },\n\n  enable(force = false) {\n    if (this.disabled || force) {\n      try {\n        nock.activate();\n      } catch (err) {}\n    }\n\n    return this;\n  }\n};\n"
  },
  {
    "path": "test/lib/utils.js",
    "content": "var Nightwatch = require('./nightwatch.js');\nconst fs = require('fs');\nconst glob = require('glob');\n\nmodule.exports = {\n\n  /**\n   * Monkey-patch run queue run() callbacks to capture errors handled\n   * in the queue after they are sent off to the nightwatch instance.\n   *\n   * @param {function} testCallback The callback used by the test to\n   * capture the error object\n   */\n  catchQueueError: function (testCallback) {\n    var queue = Nightwatch.client().queue;\n\n    // queue is a singleton, not re-instancing with new nightwatch\n    // instances. In order to re-patch it if patched previously, we\n    // restore the original run method from the patch if it exists\n    // (which may happen if a patched run never gets called with err)\n\n    if (queue.run.origRun) {\n      queue.run = queue.run.origRun;\n    }\n\n    function queueRunnerPatched (origCallback) {\n      origCallback = origCallback || function noop () {};\n      origRun.call(queue, function(err) {\n        origCallback(err);\n        if (err) {\n          queue.run = origRun; // once, since errors are fatal to queue execution\n          testCallback(err);\n        }\n      });\n    }\n\n    var origRun = queueRunnerPatched.origRun = queue.run;\n    queue.run = queueRunnerPatched;\n  },\n\n  getLineBreak: function() {\n    return process.platform === 'win32' ? '\\r\\n' : '\\n';\n  },\n\n  readFilePromise(pattern) {\n    return new Promise(function(resolve, reject) {\n      glob(pattern, (error, matches)=> {\n        if (error) {\n          return reject(error);\n        }\n        fs.readFile(matches[0], function(err, result) {\n          if (err) {\n            return reject(err);\n          }\n          \n          return resolve(result);\n        });\n      });\n    });\n  },\n\n  readDirPromise(dirName) {\n    return new Promise(function(resolve, reject) {\n      fs.readdir(dirName, function(err, result) {\n        if (err) {\n          return reject(err);\n        }\n\n        resolve(result);\n      });\n    });\n  }\n};\n"
  },
  {
    "path": "test/mocha.opts",
    "content": "--recursive\n"
  },
  {
    "path": "test/mochatests/async/sampleWithAsyncWithFailures.js",
    "content": "describe('Mocha tests with failures', function() {\n\n  //this.retries(1);\n\n  beforeEach(function(browser, callback) {\n    browser.globals.test_calls++;\n    callback();\n  });\n\n  it('demoTest', async function(browser) {\n    await browser.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .end();\n  });\n\n  it('demoTest2', function (browser) {\n    browser.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .pause(100)\n      .assert.elementPresent('#badElement')\n      .end();\n  });\n\n  it('demoTest3', function (browser) {\n    browser.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n\n  afterEach(function(browser, callback) {\n    browser.globals.test_calls++;\n    callback();\n  });\n\n});\n"
  },
  {
    "path": "test/mochatests/async/sampleWithBeforeAndAfter.js",
    "content": "describe('Demo test with Mocha', function() {\n\n  describe('for testing purposes', function() {\n\n    before(function(browser, done) {\n      browser.globals.test_calls++;\n      done();\n    });\n\n    after(function(browser, done) {\n      setTimeout(function() {\n        browser.globals.test_calls++;\n        done();\n      }, 100);\n    });\n\n    afterEach(function(browser, done) {\n      setTimeout(function() {\n        browser.globals.test_calls++;\n        done();\n      }, 100);\n    });\n\n    beforeEach(function(browser, done) {\n      setTimeout(function() {\n        browser.globals.test_calls++;\n        done();\n      }, 100);\n    });\n\n    it('demoTestAsyncOne', function(browser) {\n      browser.url('http://localhost');\n    });\n\n    it('demoTestAsyncTwo', function(browser) {\n      browser.end();\n    });\n\n  });\n});"
  },
  {
    "path": "test/mochatests/integration/sampleWithAsyncTestcase.js",
    "content": "const assert = require('assert');\n\ndescribe('Mocha tests with async testcase', function() {\n\n  this.waitForTimeout(1100);\n  this.waitForRetryInterval(100);\n  this.suiteRetries(2);\n\n  assert.deepStrictEqual(this.settings.desiredCapabilities, {browserName: 'firefox'});\n  assert.deepStrictEqual(this.argv.reporter, ['junit', 'json', 'minimalJson', 'html']);\n  assert.strictEqual(this.mochaOptions.timeout, 5000);\n  assert.strictEqual(this.waitForTimeout(), 1100);\n  assert.strictEqual(this.waitForRetryInterval(), 100);\n\n  before(async function(browser) {\n    browser.globals.test_calls++;\n\n    const result = await browser.perform(function() {\n      return browser.globals.test_calls;\n    });\n\n    assert.strictEqual(result, 1);\n  });\n\n  it('demoTest with Promise', async function (browser) {\n    const elements = await browser\n      .url('http://localhost')\n      .findElements('#weblogin');\n\n    assert.strictEqual(elements.length, 1);\n    assert.strictEqual(elements[0].getId(), '0');\n\n    browser.globals.test_calls++;\n    await browser.end();\n  });\n\n  after(async function(browser) {\n    browser.globals.test_calls++;\n    const result = await browser.perform(function() {\n      return browser.globals.test_calls;\n    });\n\n    assert.strictEqual(result, 3);\n  });\n});\n"
  },
  {
    "path": "test/mochatests/integration/sampleWithBeforeAndAfter.js",
    "content": "describe('Demo test with Mocha', function() {\n\n  describe('for testing purposes', function() {\n\n    before(function(browser, done) {\n      browser.globals.test_calls++;\n      done();\n    });\n\n    after(function(browser, done) {\n      setTimeout(function() {\n        browser.globals.test_calls++;\n        done();\n      }, 100);\n    });\n\n    afterEach(function(browser, done) {\n      setTimeout(function() {\n        browser.globals.test_calls++;\n        done();\n      }, 100);\n    });\n\n    beforeEach(function(browser, done) {\n      setTimeout(function() {\n        browser.globals.test_calls++;\n        done();\n      }, 100);\n    });\n\n    it('demoTestAsyncOne', function(browser) {\n      browser.url('http://localhost');\n    });\n\n    it('demoTestAsyncTwo', function(browser) {\n      browser.end();\n    });\n\n  });\n});"
  },
  {
    "path": "test/mochatests/integration/sampleWithFailures.js",
    "content": "describe('Mocha tests with failures', function() {\n\n  //this.retries(1);\n\n  before(function(browser, callback) {\n    browser.globals.test_calls++;\n    callback();\n  });\n\n  beforeEach(function(browser, callback) {\n    browser.globals.test_calls++;\n    callback();\n  });\n\n  it('demoTest', function (browser) {\n    browser.url('http://localhost')\n      //.pause(1000)\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .end();\n  });\n\n  it('demoTest2', function (browser) {\n    browser.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .pause(100)\n      .assert.elementPresent('#badElement')\n      .end();\n  });\n\n  it('demoTest3', function (browser) {\n    browser.url('http://localhost')\n      .pause(100)\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n\n  afterEach(function(browser, callback) {\n    browser.globals.test_calls++;\n    callback();\n  });\n\n  after(function(browser, callback) {\n    browser.globals.test_calls++;\n    callback();\n  });\n});\n"
  },
  {
    "path": "test/nightwatch.json",
    "content": "{\n  \"src_folders\" : [\"./test/src\"],\n  \"test_workers\" : false,\n  \"selenium\" : {\n    \"start_process\" : false,\n    \"start_session\" : false\n  },\n\n  \"test_settings\": {\n    \"default\" : {\n      \"filter\" : \"**/*.js\",\n      \"compatible_testcase_support\" : true,\n      \"globals\": {\n        \"asyncHookTimeout\" : 15000\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/sampletests/appendtestresult/sampleWithAppendResults.js",
    "content": "module.exports = {\n  demoTest(client) {\n    client.url('http://localhost').customCommandAppendResults().end();\n  }\n};"
  },
  {
    "path": "test/sampletests/async/test/sample.js",
    "content": "module.exports = {\n  '@desiredCapabilities': {\n    name: 'test-Async'\n  },\n\n  before(client, callback) {\n    setTimeout(function() {\n      client.globals.calls++;\n      callback();\n    }, 10);\n  },\n\n  demoTestAsync(client) {\n    client.url('http://localhost').end();\n  },\n\n  after(client, callback) {\n    setTimeout(function() {\n      client.globals.calls++;\n      callback();\n    }, 10);\n  }\n};"
  },
  {
    "path": "test/sampletests/asyncwithexpectfailures/sample.js",
    "content": "describe('browse.expect with failures in async step', function() {\n  it('async step failure', async function() {\n    browser.url('http://localhost');\n    browser.expect.element('#weblogin').to.be.contain.text('some text');\n  });\n\n  it('second step without failure', function() {\n    browser.url('http://localhost');\n    browser.expect.element('#weblogin').to.be.present;\n  });\n});"
  },
  {
    "path": "test/sampletests/asyncwithfailures/sampleWithAsyncWithFailures.js",
    "content": "describe('Mocha tests with failures', function() {\n\n  beforeEach(function(browser, callback) {\n    browser.globals.test_calls++;\n    callback();\n  });\n\n  it('demoTest', async function(browser) {\n    await browser.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n\n  it('demoTest2', function (browser) {\n    browser.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .pause(100)\n      .assert.elementPresent('#badElement')\n      .end();\n  });\n\n  it('demoTest3', async function(browser) {\n    browser.url('http://localhost')\n      .waitForElementPresent('#weblogin')\n      .waitForElementPresent('#badlogin')\n      .end();\n  });\n\n  it('demoTest4', async function(browser) {\n    await browser.url('http://localhost')\n      .waitForElementPresent('#weblogin')\n      .pause(100)\n      .waitForElementPresent('#badelement')\n      .end();\n  });\n\n  afterEach(function(browser, callback) {\n    browser.globals.test_calls++;\n    callback();\n  });\n\n});\n"
  },
  {
    "path": "test/sampletests/asyncwithfailures/sampleWithAsyncWithSingleTestFailure.js",
    "content": "\ndescribe('Mocha tests with failures', function() {\n\n  beforeEach(function(browser, callback) {\n    browser.globals.test_calls++;\n    callback();\n  });\n\n  it('demoTest', async function(browser) {\n    await browser.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n\n  afterEach(function(browser, callback) {\n    browser.globals.test_calls++;\n    callback();\n  });\n\n});\n"
  },
  {
    "path": "test/sampletests/asyncwithfailures/sampleWithBeforeAndAfter.js",
    "content": "describe('Demo test async', function () {\n\n  before(function (browser, done) {\n    browser.globals.test_calls++;\n    done();\n  });\n\n  after(function (browser, done) {\n    setTimeout(function () {\n      browser.globals.test_calls++;\n      done();\n    }, 100);\n  });\n\n  afterEach(function (browser, done) {\n    setTimeout(function () {\n      browser.globals.test_calls++;\n      done();\n    }, 100);\n  });\n\n  beforeEach(function (browser, done) {\n    setTimeout(function () {\n      browser.globals.test_calls++;\n      done();\n    }, 100);\n  });\n\n  it('demoTestAsyncOne', function (browser) {\n    browser.url('http://localhost');\n  });\n\n  it('demoTestAsyncTwo', function (browser) {\n    browser.end();\n  });\n\n});"
  },
  {
    "path": "test/sampletests/before-after/sampleSingleTest.js",
    "content": "const assert = require('assert');\n\ndescribe('samepleSingleTest', function() {\n  before(function(client, callback) {\n    let testName = client.currentTest.name;\n    assert.strictEqual(testName, '');\n    client.globals.calls++;\n    client.globals.singleTestCalled = true;\n    callback();\n  });\n\n  beforeEach(function(client, callback) {\n    var testName = client.currentTest.name;\n    assert.strictEqual(testName, 'demoTest');\n    client.globals.calls++;\n    callback();\n  });\n\n  test('demoTest', function(client) {\n    var testName = client.currentTest.name;\n    assert.strictEqual(testName, 'demoTest');\n    client.globals.calls++;\n    client.end();\n  });\n\n  afterEach(function(client, callback) {\n    var testName = client.currentTest.name;\n    assert.strictEqual(testName, 'demoTest');\n    client.globals.calls++;\n    callback();\n  });\n\n  after(function(client, callback) {\n    var testName = client.currentTest.name;\n\n    assert.strictEqual(testName, 'demoTest');\n    client.globals.calls++;\n    callback();\n  });\n});\n"
  },
  {
    "path": "test/sampletests/before-after/sampleWithBeforeAndAfter.js",
    "content": "module.exports = {\n  beforeEach: function(client, callback) {\n    setTimeout(function() {\n      client.globals.calls++;\n      callback();\n    }, 10);\n  },\n\n  before: function(client, callback) {\n    setTimeout(function() {\n      client.globals.calls++;\n      callback();\n    }, 10);\n  },\n\n  demoTestAsyncOne: function (client) {\n    client.url('http://localhost');\n  },\n\n  demoTestAsyncTwo: function (client) {\n    client.end();\n  },\n\n  afterEach: function(client, callback) {\n    setTimeout(function() {\n      client.globals.calls++;\n      callback();\n    }, 10);\n  },\n\n  after: function(client, callback) {\n    setTimeout(function() {\n      client.globals.calls++;\n      callback();\n    }, 10);\n  }\n};"
  },
  {
    "path": "test/sampletests/before-after/sampleWithBeforeAndAfterNoCallback.js",
    "content": "module.exports = {\n  before(client) {\n    client.url('http://localhost').perform(function() {\n      client.globals.calls++;\n    });\n  },\n\n  demoTestAsyncOne: function (client) {\n    client.url('http://localhost');\n  },\n\n  after(client) {\n    client.end().perform(function() {\n      client.globals.calls++;\n    });\n  }\n};"
  },
  {
    "path": "test/sampletests/before-after/syncBeforeAndAfter.js",
    "content": "var assert = require('assert');\n\nmodule.exports = {\n  before: function(client, cb) {\n    client.globals.calls++;\n    cb();\n  },\n\n  beforeEach: function(client, cb) {\n    client.globals.calls++;\n    cb();\n  },\n\n  demoTestSyncOne: function (client) {\n    client.url('http://localhost');\n    var testName = client.currentTest.name;\n    assert.strictEqual(testName, 'demoTestSyncOne');\n  },\n\n  demoTestSyncTwo: function (client) {\n    var testName = client.currentTest.name;\n    assert.strictEqual(testName, 'demoTestSyncTwo');\n    client.end();\n  },\n\n  afterEach: function(client) {\n    client.globals.calls++;\n  },\n\n  after: function(client) {\n    client.globals.calls++;\n  }\n};"
  },
  {
    "path": "test/sampletests/beforewithcommand/commandInsideBefore.js",
    "content": "var assert = require('assert');\n\nmodule.exports = {\n  before: function(client, cb) {\n    client.assert.ok(false);\n    client.globals.calls++;\n    cb();\n  },\n\n  beforeEach: function(client, cb) {\n    client.globals.calls++;\n    cb();\n  },\n\n  demoTestSyncOne: function (client) {\n    client.url('http://localhost');\n    var testName = client.currentTest.name;\n    assert.strictEqual(testName, 'demoTestSyncOne');\n  },\n\n  demoTestSyncTwo: function (client) {\n    var testName = client.currentTest.name;\n    assert.strictEqual(testName, 'demoTestSyncTwo');\n    client.end();\n  },\n\n  afterEach: function(client, cb) {\n    client.globals.calls++;\n    client.end(cb);\n  },\n\n  after: function(client) {\n    client.globals.calls++;\n  }\n};"
  },
  {
    "path": "test/sampletests/beforewithcommand/commandInsideBeforeWithNoParams.js",
    "content": "var assert = require('assert');\n\nmodule.exports = {\n  before: function() {\n    browser.assert.ok(false);\n    browser.globals.calls++;\n  },\n\n  beforeEach: function(client, cb) {\n    client.globals.calls++;\n    cb();\n  },\n\n  demoTestSyncOne: function (client) {\n    client.url('http://localhost');\n    var testName = client.currentTest.name;\n    assert.strictEqual(testName, 'demoTestSyncOne');\n  },\n\n  demoTestSyncTwo: function (client) {\n    var testName = client.currentTest.name;\n    assert.strictEqual(testName, 'demoTestSyncTwo');\n    client.end();\n  },\n\n  afterEach: function(client) {\n    client.globals.calls++;\n  },\n\n  after: function(client) {\n    client.globals.calls++;\n  }\n};"
  },
  {
    "path": "test/sampletests/empty/.gitignore",
    "content": "*.js"
  },
  {
    "path": "test/sampletests/es6await/basicSampleTest.js",
    "content": "const assert = require('assert');\n\ndescribe('basicSampleTest', function() {\n\n  it('basic test with ES6 async/await', async (browser) => {\n    const currentUrl = await browser.url('http://localhost').url();\n    assert.strictEqual(currentUrl, 'http://localhost');\n\n    const assertResult = await browser.assert.elementPresent('#weblogin', function(result) {\n      assert.deepStrictEqual(result, {value: [{ELEMENT: '0'}], status: 0, returned: 1, passed: true});\n    });\n\n    assert.deepStrictEqual(assertResult, {value: [{ELEMENT: '0'}], status: 0, returned: 1, passed: true});\n\n    await browser.end();\n  });\n\n  it('basic test with ES6 async/await and no await commands', async (browser) => {\n    browser\n      .url('http://localhost')\n      .assert.elementPresent('#weblogin');\n\n    browser.assert.strictEqual(0, 1)\n  });\n\n  it('test with ES6 async/await assertion error and try/catch', async (browser) => {\n    let error;\n    try {\n      await browser.assert.elementPresent('#badelement');\n    } catch (err) {\n      error = err;\n    }\n\n    assert.ok(error instanceof Error);\n    assert.strictEqual(error.name, 'NightwatchAssertError');\n\n    await browser.end();\n  });\n\n  xit('test with ES6 async/await perform error and try/catch', async (browser) => {\n    let error;\n    try {\n      await browser.perform(async function() {\n        throw new Error('Error from perform');\n      });\n    } catch (err) {\n      error = err;\n    }\n\n    assert.ok(error instanceof Error);\n    assert.strictEqual(error.message, 'Error while running \"perform\" command: Error from perform');\n\n    await browser.end();\n  });\n});"
  },
  {
    "path": "test/sampletests/es6await/incorrect-element-args/sampleTestProperty.js",
    "content": "describe('element commands with incorrect args', function() {\n  it('getElementProperty', async function(browser) {\n    await browser.getElementProperty('aside');\n  })\n})"
  },
  {
    "path": "test/sampletests/es6await/selenium/basicSampleTestSelenium.js",
    "content": "const assert = require('assert');\n\ndescribe('basicSampleTest', function() {\n\n  it('basic test with ES6 async/await', async (browser) => {\n    const currentUrl = await browser.url('http://localhost').url();\n    assert.strictEqual(currentUrl, 'http://localhost');\n\n    const assertResult = await browser.assert.elementPresent('#weblogin', function(result) {\n      assert.deepStrictEqual(result, {value: [{ELEMENT: '0'}], status: 0, returned: 1, passed: true});\n    });\n\n    assert.deepStrictEqual(assertResult, [{ELEMENT: '0'}]);\n\n    await browser.end();\n  });\n});"
  },
  {
    "path": "test/sampletests/es6await/selenium/failures/sampleWithFailures.js",
    "content": "const assert = require('assert');\n\ndescribe('sampleWithFailures', function() {\n  it('asyncGetCookiesTest', async function (client) {\n    await client.url('http://localhost');\n\n    const cookies = await client.getCookies();\n    assert.strictEqual(cookies[0].name, 'test_cookie');\n\n    client.end();\n  });\n\n  it('demoTest2', async function (client) {\n    await client.url('http://localhost');\n\n    client.assert.elementPresent('#weblogin');\n    await client.assert.elementPresent({\n      selector: '#badElement',\n      timeout: 15,\n      retryInterval: 15\n    });\n\n    client.end();\n  });\n\n  it('verify', async function (client) {\n    await client.url('http://localhost');\n    await client.verify.elementPresent({\n      selector: '#badElement',\n      timeout: 25,\n      retryInterval: 15\n    })\n      .verify.elementPresent('#weblogin');\n\n    client.end();\n  });\n\n  it('waitFor', async function(client) {\n    await client.url('http://localhost');\n    await client.waitForElementVisible({\n      selector: '#badElement',\n      timeout: 15,\n      retryInterval: 15,\n      abortOnFailure: false\n    });\n\n    client.end();\n  });\n});\n\n"
  },
  {
    "path": "test/sampletests/es6await/selenium/getlog/getLogTestES6.js",
    "content": "const assert = require('assert');\n\nmodule.exports = {\n  'getLog() test with ES6 async/await': async (client) => {\n    client.url('http://localhost');\n\n    const logResult = await client.getLog();\n    assert.strictEqual(Array.isArray(logResult), true);\n    assert.strictEqual(logResult.length, 2);\n\n    const logResultCallback = await client.getLog('browser', function(result) {\n      return result;\n    });\n    assert.strictEqual(Array.isArray(logResultCallback), true);\n    assert.strictEqual(logResultCallback.length, 2);\n\n    let interval = new Date().getTime();\n    const logResultBrowser = await client.getLog(function(result) {\n      return new Promise(function(resolve) {\n        setTimeout(function() {\n          interval = new Date().getTime() - interval;\n          resolve();\n        }, 20);\n      });\n    });\n\n    assert.strictEqual(Array.isArray(logResultBrowser), true);\n    assert.strictEqual(logResultBrowser.length, 2);\n    assert.strictEqual(interval >= 20, true, `Expected interval greater than 20 ms but got ${interval}`);\n\n    await client.end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/es6await/webdriver/getText/getTextES6.js",
    "content": "const assert = require('assert');\n\nmodule.exports = {\n  'getText() test with ES6 async/await': async (client) => {\n    client.url('http://localhost');\n\n    const page = client.page.simplePageObj();\n\n    const result = await client.findElements('#element-selector');\n    assert.ok(result[0]);\n    assert.ok('element-6066-11e4-a52e-4f735466cecf' in result[0]);\n    assert.strictEqual(result[0].getId(), '5cc459b8-36a8-3042-8b4a-258883ea642b');\n    assert.strictEqual(result[0]['element-6066-11e4-a52e-4f735466cecf'], '5cc459b8-36a8-3042-8b4a-258883ea642b');\n\n    const elementSelector = await client.findElement('#element-selector');\n    assert.ok(elementSelector);\n    assert.ok('element-6066-11e4-a52e-4f735466cecf' in elementSelector);\n    assert.strictEqual(elementSelector.getId(), '5cc459b8-36a8-3042-8b4a-258883ea642b');\n    assert.strictEqual(elementSelector['element-6066-11e4-a52e-4f735466cecf'], '5cc459b8-36a8-3042-8b4a-258883ea642b');\n\n    const textResult = await page.getText('#element-selector');\n    assert.ok(!!textResult);\n    assert.strictEqual(textResult, 'sample text value');\n\n    const resultSection = await page.section.signUp.getText('@help');\n    assert.strictEqual(resultSection, 'help text value');\n  }\n\n\n};\n"
  },
  {
    "path": "test/sampletests/isPresent/elementNotPresent.js",
    "content": "describe('test', function () {\n  test('test isPresent', async (browser) => {\n    browser\n      .element('#wrong').isPresent().assert.equals(false);\n  });\n});\n"
  },
  {
    "path": "test/sampletests/mixed/sample.js",
    "content": "var assert = require('assert');\n\nmodule.exports = {\n  demoTestMixed(client) {\n    client.url('http://localhost').end();\n  },\n\n  afterEach(client, callback) {\n    setTimeout(function () {\n      assert.strictEqual(client.currentTest.results.passed, 0);\n      assert.strictEqual(client.currentTest.results.failed, 0);\n      assert.strictEqual(client.currentTest.results.errors, 0);\n      assert.strictEqual(client.currentTest.results.skipped, 0);\n      assert.strictEqual(client.currentTest.results.tests, 0);\n\n      callback();\n    }, 10);\n  }\n};"
  },
  {
    "path": "test/sampletests/mixed-files/sampleJs.js",
    "content": "module.exports = {\n  '@desiredCapabilities': {\n    name: 'test-Name'\n  },\n  demoTest: function (client) {\n    client.assert.equal(client.options.desiredCapabilities.name, 'test-Name');\n  \n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin');\n  },\n  \n  after: function (client) {\n    client.end();\n  }\n};\n  "
  },
  {
    "path": "test/sampletests/mixed-files/sampleTs.ts",
    "content": "module.exports = {\n  demoTest: function(client: any) {\n    client.url('http://localhost')\n      .typescript.tsWait(10)\n      .assert.elementPresent('#weblogin');\n  },\n\n  after: function(client: any) {\n    client.end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/passwordValueRedacted/passwordValueRedacted.js",
    "content": "describe('value redaction in setPassword', function() { \n  test('test setPassword', async browser => {\n    browser\n      .setPassword('#weblogin', 'password')\n      .setValue('#weblogin', 'simpletext');\n  });\n});\n"
  },
  {
    "path": "test/sampletests/reusebrowser/firstTest.js",
    "content": "module.exports = {\n  '@desiredCapabilities': {\n    name: 'first-test'\n  },\n\n  before(client, callback) {\n    setTimeout(function() {\n      client.globals.calls++;\n      callback();\n    }, 10);\n  },\n\n  demoTestAsync(client) {\n    client.url('http://localhost');\n  },\n\n  after(client, callback) {\n    setTimeout(function() {\n      client.globals.calls++;\n      client.end();\n      callback();\n    }, 10);\n  }\n};"
  },
  {
    "path": "test/sampletests/reusebrowser/secondTest.js",
    "content": "module.exports = {\n  '@desiredCapabilities': {\n    name: 'second-test'\n  },\n\n  before(client, callback) {\n    setTimeout(function() {\n      client.globals.calls++;\n      callback();\n    }, 10);\n  },\n\n  demoTestAsync(client) {\n    client.url('http://localhost');\n  },\n\n  after(client, callback) {\n    setTimeout(function() {\n      client.globals.calls++;\n      client.end();\n      callback();\n    }, 10);\n  }\n};"
  },
  {
    "path": "test/sampletests/sampleforreport/sample.js",
    "content": "module.exports = {\n  '@desiredCapabilities': {\n    name: 'test-Name'\n  },\n  demoTest: function (client) {\n    client.assert.equal(client.options.desiredCapabilities.name, 'test-Name');\n\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin');\n  },\n\n  afterEach: function (client) {\n    client.assert.equal(client.options.desiredCapabilities.name, 'test-Name');\n  },\n\n  after: function (client) {\n    client.end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/sampleforreport/sampleWithFailure.js",
    "content": "module.exports = {\n  '@desiredCapabilities': {\n    name: 'test-Name'\n  },\n  demoTest: function (client) {\n    client.assert.equal(client.options.desiredCapabilities.name, 'test-Name');\n\n    client.url('http://localhost')\n      .assert.elementPresent('#badElement');\n  },\n\n  afterEach: function (client) {\n    client.assert.equal(client.options.desiredCapabilities.name, 'test-Name');\n  },\n\n  after: function (client) {\n    client.assert.equal(client.options.desiredCapabilities.name, 'test-Name');\n    client.end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/simple/test/sample.js",
    "content": "module.exports = {\n  '@desiredCapabilities': {\n    name: 'test-Name'\n  },\n  demoTest: function (client) {\n    client.assert.equal(client.options.desiredCapabilities.name, 'test-Name');\n\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin');\n  },\n\n  after: function (client) {\n    client.end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/srcfolders/other_sample.js",
    "content": "var assert = require('assert');\nmodule.exports = {\n  desiredCapabilities: {\n    name: 'test-srcFolders'\n  },\n  srcFoldersTest: function (client) {\n    assert.strictEqual(client.options.desiredCapabilities.name, 'test-srcFolders');\n  }\n};\n"
  },
  {
    "path": "test/sampletests/suiteretries/locate-strategy/suiteRetriesLocateStrategy.js",
    "content": "var failFirstTime = true;\n\nmodule.exports = {\n  before(client) {\n    client.url('http://localhost');\n  },\n\n  after(client) {\n    client.end();\n  },\n\n  demoStep1(client) {\n    client\n      .assert.elementPresent('#weblogin')\n      .elements('css selector', '#weblogin', function() {\n        if (failFirstTime) {\n          client.useXpath();\n        }\n      })\n      .perform(function() {\n        if (failFirstTime) {\n          failFirstTime = false;\n\n          return client.assert.ok(false);\n        }\n      });\n  }\n\n};\n"
  },
  {
    "path": "test/sampletests/suiteretries/sample/suiteRetriesSample.js",
    "content": "var failFirstTime = true;\n\nmodule.exports = {\n  before: function (client) {\n    client.url('http://localhost');\n  },\n\n  after: function (client) {\n    client.end();\n  },\n\n  demoStep1: function (client) {\n    client\n      .assert.elementPresent('#weblogin')\n      .perform(function() {\n        client.globals.calls++;\n      });\n  },\n\n  demoStep2: function (client) {\n    client\n      .elements('css selector', '#weblogin', function() {\n        if (failFirstTime) {\n          failFirstTime = false;\n          client.assert.ok(false);\n        }\n\n        client\n          .assert.elementPresent('#weblogin')\n          .perform(function() {\n            client.globals.calls++;\n          });\n      });\n  }\n\n};\n"
  },
  {
    "path": "test/sampletests/syncnames/sampleTest.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .waitForElementVisible('#finlandia', 1000)\n      .waitForElementVisible('#finlandia')\n      .assert.containsText('#finlandia', 'sibelius');\n  },\n\n  after(client) {\n    client.end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/tags/sample.js",
    "content": "module.exports = {\n  tags: ['login', 'other'],\n  demoTagTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/tagswithbrowserobject/sample.js",
    "content": "describe('Sample test with tags and global browser object', function() {\n  const globals = browser.globals;\n  this.tags = ['browser'];\n  it('demoTagTest', function(browser) {\n    browser\n      .url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n});"
  },
  {
    "path": "test/sampletests/trace/sample.js",
    "content": "describe('Sample test with traceable commands', function() {\n\n  before(browser => {\n    browser\n      .navigateTo('http://localhost');\n  });\n\n  it('click_on_web_login', function(browser) {\n    browser\n      .assert.visible('#weblogin')\n      .click('#weblogin');\n  });\n\n  after(browser => browser.end());\n});"
  },
  {
    "path": "test/sampletests/typescript/sample.ts",
    "content": "module.exports = {\n  demoTest: function(client: any) {\n    client.url('http://localhost')\n      .typescript.tsWait(10)\n      .assert.elementPresent('#weblogin');\n  },\n\n  after: function(client: any) {\n    client.end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/unittests/sample.js",
    "content": "var assert = require('assert');\nmodule.exports = {\n  demoTestSync() {\n    assert.strictEqual(0, 0);\n  },\n\n  demoTestAsync(done) {\n    setTimeout(function () {\n      done();\n    }, 10);\n  }\n};\n"
  },
  {
    "path": "test/sampletests/unittests/sampleAnnotation.js",
    "content": "module.exports = {\n  '@unitTest': true,\n  demoSync() {\n    this.client.globals.calls++;\n  },\n\n  demoTestAsync(done) {\n    this.client.globals.calls++;\n    setTimeout(function () {\n      done();\n    }, 10);\n  }\n};\n"
  },
  {
    "path": "test/sampletests/unknown-method/UnknownMethod.js",
    "content": "describe('sample test goes here', function () {\n  it('failure stack trace', function() {\n   \n    browser.url('http://localhost')\n      .assert.elementPresen('#badElement'); // mispelled API method\n  });\n}); "
  },
  {
    "path": "test/sampletests/usexpath/sample.js",
    "content": "module.exports = {\n  demoTestXpath: function (client) {\n    client\n      .url('http://localhost')\n      .useXpath()\n      .waitForElementPresent('//weblogin', 50, function(result) {\n        client.globals.test.equals(result.status, 0);\n        client.globals.test.deepEqual(result.value, [{ELEMENT: '0'}]);\n      })\n      .useCss()\n      .end();\n  },\n\n  after: function(client, callback) {\n    process.nextTick(function() {\n      client.end();\n      client.globals.test.ok('after callback called');\n      callback();\n    });\n  }\n};\n"
  },
  {
    "path": "test/sampletests/usingwithin/testNoWithin.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client\n      .url('http://localhost')\n      .waitForElementVisible('#finlandia', 1000)\n  },\n\n  after(client) {\n    client.end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/usingwithin/testWithin.js",
    "content": "module.exports = {\n  demoTest: async function (browser) {\n    browser.url('http://localhost');\n\n    const context = browser.within('#weblogin');\n    const result = await context.click('button');\n\n    browser.assert.strictEqual(typeof context.assert, 'undefined');\n    browser.assert.strictEqual(typeof context.debug, 'undefined');\n    //browser.assert.strictEqual(typeof context.customClearValue, 'function', 'customClearValue should be loaded');\n  }\n};\n"
  },
  {
    "path": "test/sampletests/webelement/findWithSuppressNotFoundErrors.js",
    "content": "describe('test', function () {\n  test('test find with suppressNotFoundErrors', async (browser) => {\n    browser.element.find({\n      selector: browser.globals.selector,\n      suppressNotFoundErrors: browser.globals.suppressNotFoundErrors\n    });\n  });\n});\n"
  },
  {
    "path": "test/sampletests/withaftereach/sampleSingleTest.js",
    "content": "var assert = require('assert');\n\nmodule.exports = {\n  beforeEach: function(client, callback) {\n    var testName = client.currentTest.name;\n    assert.deepStrictEqual(testName, 'demoTest');\n    callback();\n  },\n\n  before: function(client, callback) {\n    var testName = client.currentTest.name;\n    assert.deepStrictEqual(testName, '');\n    callback();\n  },\n\n  demoTest: function (client) {\n    var testName = client.currentTest.name;\n    client.assert.ok('Test OK');\n    client.assert.equal(1, 1);\n    client.assert.not.equal(1, 0);\n    assert.strictEqual(testName, 'demoTest');\n    client.end();\n  },\n\n  afterEach: function(client, callback) {\n    var testName = client.currentTest.name;\n    var results = client.currentTest.results;\n\n    assert.strictEqual(results.passed, 3);\n    assert.strictEqual(results.failed, 0);\n    assert.strictEqual(results.tests, 3);\n    assert.ok('demoTest' in results.testcases);\n    assert.strictEqual(results.testcases.demoTest.assertions.length, 3);\n    assert.deepStrictEqual(testName, 'demoTest');\n    callback();\n  },\n\n  after: function(client, callback) {\n    var testName = client.currentTest.name;\n    assert.deepStrictEqual(testName, 'demoTest');\n    callback();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withasynchooks/sampleAsyncHooks.js",
    "content": "module.exports = {\n  before: function(client, callback) {\n    client.perform(function() {\n      client.globals.calls++;\n      callback();\n    });\n  },\n\n  beforeEach: function(client, callback) {\n    client.perform(function() {\n      setTimeout(function() {\n        client.globals.calls++;\n        callback();\n      }, 10);\n    });\n  },\n\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  demoTest2: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  },\n\n  afterEach: function(client, callback) {\n    client.perform(function() {\n      setTimeout(function() {\n        client.globals.calls++;\n        callback();\n      }, 10);\n    });\n  },\n\n  after: function(client, callback) {\n    client\n      .customPerform(function() {\n        client.globals.calls++;\n      })\n      .perform(function() {\n        setTimeout(function() {\n          client.globals.calls++;\n          callback();\n        }, 10);\n      });\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withchaiexpect/sampleWithChai.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost');\n    client.expect.element('#weblogin').to.be.present;\n    client.end();\n  },\n\n  demoTest1: function (client) {\n    client.url('http://localhost');\n\n    expect(element('#weblogin')).to.be.present;\n\n    client.end();\n  },\n\n  demoTest2: function (client) {\n    client.url('http://localhost')\n      .elements('css selector', '#weblogin', async function (result) {\n        client.globals.test.ok(result.value);\n\n\n        let assertion = client.expect(result.value).to.have.length(1);\n        let value = await assertion.__flags.get('object');\n\n        client.globals.test.deepEqual(value, [{ELEMENT: '0'}]);\n\n        await client.expect(result.value).to.have.length(2);\n\n      })\n      .end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withchaiexpect/sampleWithGlobalExpect.js",
    "content": "module.exports = {\n  demoTest: async function (client) {\n    const result = await client.url('http://localhost')\n      .elements('css selector', '#weblogin');\n\n    expect(result).to.have.length(1);\n    expect(null).to.be.null;\n  },\n\n  demoTestWithError: function () {\n    expect('#weblogin').to.be.present;\n  }\n\n};\n"
  },
  {
    "path": "test/sampletests/withcommanderrors/demoTest.js",
    "content": "module.exports = {\n  'Demo test': function (browser) {\n    browser\n      .url('http://localhost')\n      .waitForElementPresent('#weblogin')\n      .pause(100)\n      .frameParent()\n      .end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withcustomcommands/element/withCustomElementCommand.js",
    "content": "module.exports = {\n  before(client) {\n    client.globals.increment++;\n  },\n\n  'sample test with custom element command' (client) {\n    client.url('http://localhost').customElementPresent('#weblogin').end();\n  },\n\n  after(client) {\n    client.globals.increment++;\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withcustomcommands/sampleWithAsyncFailures.js",
    "content": "module.exports = {\n  before(client) {\n    client.globals.increment++;\n  },\n\n  async demoTestAsync(client) {\n    await client.url('http://localhost').customCommandWithFailureClass();\n    // below statement should be unreachable because the custom command should be rejected\n    client.globals.increment++;\n  },\n\n  after(client) {\n    client.globals.increment++;\n  }\n};"
  },
  {
    "path": "test/sampletests/withcustomcommands/sampleWithFailures.js",
    "content": "module.exports = {\n  before(client) {\n    client.globals.increment++;\n  },\n\n  demoTestAsync(client) {\n    client.url('http://localhost').customCommandWithFailure().end();\n  },\n\n  after(client) {\n    client.globals.increment++;\n  }\n};"
  },
  {
    "path": "test/sampletests/withdescribe/basic/sample.js",
    "content": "describe('basic describe test', function () {\n\n  this.desiredCapabilities = {\n    name: 'basicDescribe'\n  };\n\n  test('demoTest', function (client) {\n    client.assert.strictEqual(client.options.desiredCapabilities.name, 'basicDescribe');\n\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin');\n  });\n\n  after(function (client) {\n    client.end();\n  });\n});\n\n"
  },
  {
    "path": "test/sampletests/withdescribe/basic/sampleWithOnly.js",
    "content": "describe('basic describe test', function () {\n\n  this.desiredCapabilities = {\n    name: 'basicDescribe'\n  };\n\n  this.timeout(55);\n  this.tags = ['something'];\n  this.endSessionOnFail = false;\n  this.skipTestcasesOnFail = false;\n\n  test('demoTest one', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin');\n  });\n\n  test.only('demoTest two', function (client) {\n    client.assert.strictEqual(client.options.globals.waitForConditionTimeout, 55);\n    client.assert.strictEqual(this.settings.desiredCapabilities.name, 'basicDescribe');\n\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin');\n  });\n\n  test('demoTest three', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin');\n  });\n});\n\n"
  },
  {
    "path": "test/sampletests/withdescribe/basic2/sample.js",
    "content": "const assert = require('assert');\n\ndescribe('basic describe test', async function () {\n  const nwClient = this['[client]'];\n\n  const asynctreeEventListener = () => {\n    this.globals.asynctreeFinishedEventCount++;\n  };\n\n  const queueEventListener = () => {\n    this.globals.queueFinishedEventCount++;\n  };\n\n  this.desiredCapabilities = {\n    name: 'basicDescribe'\n  };\n\n  test('with awaited JS command bw Nightwatch commands', async function (client) {\n    nwClient.queue.tree.on('asynctree:finished', asynctreeEventListener);\n\n    // queue event listeners are automatically removed after\n    // every (test case + afterEach + after (if applicable))\n    // so, no need to remove this listener manually before next test case run.\n    nwClient.queue.on('queue:finished', queueEventListener);\n\n    await client.assert.strictEqual(client.options.desiredCapabilities.name, 'basicDescribe');\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 1);\n\n    await client.url('http://localhost');\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 2);\n\n    await new Promise((resolve) => {\n      setTimeout(function() {\n        resolve(null);\n      }, 50);\n    });\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 2);\n\n    await client.assert.elementPresent('#weblogin');\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 3);\n\n    // queue:finished event shouldn't be emitted in between the test.\n    assert.equal(this.globals.queueFinishedEventCount, 0);\n  });\n\n  test('with await in last command', async function (client) {\n    nwClient.queue.tree.on('asynctree:finished', asynctreeEventListener);\n\n    await client.assert.strictEqual(client.options.desiredCapabilities.name, 'basicDescribe');\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 1);\n\n    await client.url('http://localhost');\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 2);\n\n    await client.assert.elementPresent('#weblogin');\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 3);\n  });\n\n  test('without await in last command', async function (client) {\n    nwClient.queue.tree.on('asynctree:finished', asynctreeEventListener);\n\n    await client.assert.strictEqual(client.options.desiredCapabilities.name, 'basicDescribe');\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 1);\n\n    await client.url('http://localhost');\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 2);\n\n    client.assert.elementPresent('#weblogin');\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 3);\n  });\n\n  afterEach(function () {\n    nwClient.queue.tree.removeListener('asynctree:finished', asynctreeEventListener);\n    assert.equal(nwClient.queue.tree.rootNode.childNodes.length, 0);\n  });\n\n  after(function (client) {\n    client.end();\n  });\n});\n"
  },
  {
    "path": "test/sampletests/withdescribe/failures/sampleSkipTestcases.js",
    "content": "const assert = require('assert');\n\ndescribe('sample test with skipTestcasesOnFail', function () {\n  this.skipTestcasesOnFail = false;\n  this.endSessionOnFail = false;\n\n  this.waitForTimeout(10);\n  this.waitForRetryInterval(5);\n\n  this.tags = ['login'];\n\n  assert.strictEqual(this.waitForTimeout(), 10);\n  assert.strictEqual(this.waitForRetryInterval(), 5);\n\n  assert.strictEqual(this.globals.waitForConditionTimeout, 10);\n  assert.strictEqual(this.globals.retryAssertionTimeout, 10);\n  assert.strictEqual(this.globals.waitForConditionPollInterval, 5);\n\n  let endFn;\n\n  before(function (client, done) {\n    endFn = client.end;\n    done();\n  });\n\n  it('demoTest', function (client) {\n    client.globals.calls++;\n\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement');\n  });\n\n  it('demoTest2', function (client) {\n    client.globals.calls++;\n\n    client.end = function () {\n      client.assert.fail('End should not be called.');\n    };\n\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement');\n  });\n\n  after(function (client, done) {\n    client.end = endFn;\n    done();\n  });\n});\n"
  },
  {
    "path": "test/sampletests/withdescribe/failures/sampleTest.js",
    "content": "describe('sample test with failures', function() {\n  before(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  beforeEach(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  it('demoTest', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .assert.elementPresent('#webLogin')\n      .end();\n  });\n\n  it('demoTest2', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .end();\n  });\n\n  afterEach(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  after(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n});\n\n\n"
  },
  {
    "path": "test/sampletests/withdescribe/failures/sampleTestWithAttribute.js",
    "content": "describe('sample test with failures and attribute', function() {\n  this.retries(1);\n\n  before(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  beforeEach(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  it('demoTest', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .assert.elementPresent('#webLogin')\n      .end();\n  });\n\n  it('demoTest2', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .end();\n  });\n\n  afterEach(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  after(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n});\n\n\n"
  },
  {
    "path": "test/sampletests/withdescribe/skipped/duplicateTestcases.js",
    "content": "describe('test', function () {\n  test('test find', async (browser) => {\n    browser.globals.calls++;\n    browser.element.find('#weblogin');\n  });\n\n  test('test find', async (browser) => {\n    browser.globals.calls++;\n    browser.element.find('#weblogin');\n  });\n});\n"
  },
  {
    "path": "test/sampletests/withdescribe/skipped/skipBeforeAfterEach.js",
    "content": "describe('sample test with failures', function() {\n  beforeEach(function (client) {\n    client.globals.calls++;\n  });\n\n  it('demoTest', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n  \n  it('demoTest2', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n  \n  it.skip('demoTest3', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n  \n  xit('demoTest4', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n  \n  xtest('demoTest5', function (client) { // eslint-disable-line no-undef\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n\n  afterEach(function (client) {\n    client.globals.calls++;\n  });\n});\n  \n  \n  "
  },
  {
    "path": "test/sampletests/withdescribe/skipped/skipTestcase.js",
    "content": "describe('sample test with failures', function() {\n  it('demoTest', function (client) {\n    client.globals.calls++;\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n\n  it('demoTest2', function (client) {\n    client.globals.calls++;\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n\n  it.skip('demoTest3', function (client) {\n    client.globals.calls++;\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n\n  xit('demoTest4', function (client) {\n    client.globals.calls++;\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n\n  xtest('demoTest5', function (client) { // eslint-disable-line no-undef\n    client.globals.calls++;\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n});\n\n\n"
  },
  {
    "path": "test/sampletests/withdescribe/skipped/skipTestsuite.js",
    "content": "xdescribe('sample test with failures', function() {\n  it('demoTest', function (client) {\n    client.globals.calls++;\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n\n  it('demoTest2', function (client) {\n    client.globals.calls++;\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  });\n});\n\n\n"
  },
  {
    "path": "test/sampletests/withdescribe/suite-retries/sample.js",
    "content": "describe('sample with suiteRetries', function() {\n  before(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  beforeEach(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  test('demoTest', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .assert.elementPresent('#webLogin')\n      .end();\n  });\n\n  test('demoTest2', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .end();\n  });\n\n  afterEach(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  after(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n});\n"
  },
  {
    "path": "test/sampletests/withdescribe/suite-retries/sampleWithAttribute.js",
    "content": "describe('sample with suiteRetries', function() {\n  this.suiteRetries(1);\n\n  before(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  beforeEach(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  test('demoTest', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .assert.elementPresent('#webLogin')\n      .end();\n  });\n\n  test('demoTest2', function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .end();\n  });\n\n  afterEach(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n\n  after(function(client, callback) {\n    client.globals.calls++;\n    callback();\n  });\n});\n"
  },
  {
    "path": "test/sampletests/withdescribe/unittests/sampleAnnotationWithDescribe.js",
    "content": "describe('sample test with describe', function() {\n  this.unitTest = true;\n\n  test('demoSync', () => {\n    this.client.globals.calls++;\n  });\n\n  test('demoTestAsync', (done) => {\n    this.client.globals.calls++;\n    setTimeout(function () {\n      done();\n    }, 10);\n  });\n});\n"
  },
  {
    "path": "test/sampletests/withelementerrors/sampleTestWithElementError.js",
    "content": "describe('sample test with element error', function () {\n\n  test('demoTest', (client) => {\n    client\n      .url('http://localhost')\n      .click('#element-error')\n      .waitForElementPresent('#weblogin');\n  });\n\n  after(client => client.end());\n});\n\n"
  },
  {
    "path": "test/sampletests/witherrors/sampleWithError.js",
    "content": "module.exports = {\n  demoTest: function () {\n    throw new Error('Error in test script');\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withes6asynccommands/sampleWithAsyncCommands.js",
    "content": "module.exports = {\n  demoTest: async function (client) {\n    client.url('http://localhost');\n    client.basicPerform(function() {\n      client.globals.increment++;\n    });\n    client.customPerform(function() {\n      client.globals.increment++;\n    });\n    client.customPerformClass(function() {\n      client.globals.increment++;\n    });\n    client.customPerformClass();\n\n    await client.basicPerformWithFluentApi(function() {});\n\n    client.end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withexclude/excluded/excluded-module.js",
    "content": "module.exports = {\n  demoTestExcluded: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withexclude/excluded/not-excluded.js",
    "content": "module.exports = {\n  demoTestExcluded: function (client) {\n    client.url('http://localhost').end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withexclude/simple/sample.js",
    "content": "module.exports = {\n  demoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withfailures/sample.js",
    "content": "module.exports = {\n  before(client, callback) {\n    client.globals.calls++;\n    callback();\n  },\n\n  beforeEach(client, callback) {\n    client.globals.calls++;\n    callback();\n  },\n\n  demoTest(client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .assert.elementPresent('#webLogin')\n      .end();\n  },\n\n  demoTest2(client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .assert.elementPresent('#badElement')\n      .end();\n  },\n\n  afterEach(client, callback) {\n    client.globals.calls++;\n    callback();\n  },\n\n  after(client, callback) {\n    client.globals.calls++;\n    callback();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withpageobjects/useXpathWithPageObjects.js",
    "content": "module.exports = {\n  before(c) {\n    c.useXpath();\n  },\n\n  'waitFor element visible after xpath': (client) => {\n    client.url('http://localhost');\n\n    const page = client.page.simplePageObj();\n    page.waitForElementPresent('@loginAsString', 10);\n\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withservererrors/sampleTestWithServerError.js",
    "content": "describe('sampleTestWithServerError', function() {\n  beforeEach(() => {\n    // FIXME: when disabling testcases with xit() or xtest(), test hooks should also be skipped\n    // console.log('before each')\n  });\n\n  it('demoTestWithElementCommand', client => {\n    client.getTagName('#element-server-error');\n  });\n\n  it('demoTest', client => {\n    client.assert.not.elementPresent('#element-server-error');\n  });\n\n  it('demoTestWithExpect', client => {\n    client.expect.element('#element-server-error').not.present;\n  });\n\n  it('demoTestWithWaitForElement', client => {\n    client.waitForElementNotPresent('#element-server-error');\n  });\n\n\n\n  after(client => {\n    client.end();\n  });\n});\n\n"
  },
  {
    "path": "test/sampletests/withsubfolders/simple/sample.js",
    "content": "module.exports = {\n  simpleDemoTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withsubfolders/tags/sampleTags.js",
    "content": "module.exports = {\n  tags: ['login', 'logout'],\n  otherDemoTagTest: function (client) {\n    client.url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withuknownRequire/sample.js",
    "content": "const util = require('utilWhichDoesnotexist.js');\n\nmodule.exports = {\n  demoTest: function (client) {\n\n    var resultMs = util.formatElapsedTime(999);\n    client.assert.equal(resultMs, '999ms');\n  },\n\n  after: function (client) {\n    client.end();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withuncaughterrors/demoTestFine.js",
    "content": "describe('passing test', function () {\n\n  this.tags = ['uncaught-error'];\n\n  test('demo Test Passing', function (client) {\n    client\n      .url('http://localhost')\n      .assert.elementPresent('#weblogin')\n      .waitForElementPresent('#weblogin');\n  });\n\n});\n\n"
  },
  {
    "path": "test/sampletests/withuncaughterrors/demoTestWithError.js",
    "content": "describe('test with uncaught error', function () {\n\n  this.tags = ['uncaught-error'];\n\n  test('Passing test step', function (client) {\n    client\n      .url('http://localhost')\n      .assert.elementPresent('#weblogin');\n  });\n\n  test('Uncaught error test step', function (client) {\n    client.assert.elementPresent('#weblogin');\n\n    setTimeout(function () {\n      throw new Error('Test Error Uncaught');\n    }, 100);\n  });\n\n});\n\n"
  },
  {
    "path": "test/sampletests/withverify/verifySampleFailures.js",
    "content": "module.exports = {\n  before(client) {\n    client.globals.calls++;\n    client.url('http://localhost');\n  },\n\n  demoTest(client) {\n    client.verify.equal(0, 1, 'custom message')\n      .verify.elementPresent('#weblogin')\n      .verify.elementPresent('#badElement');\n  },\n\n  demoTest1(client) {\n    client.verify.equal(0, 0, 'custom message');\n  },\n\n  after(client, callback) {\n    client.end();\n    client.globals.calls++;\n    callback();\n  }\n};\n"
  },
  {
    "path": "test/sampletests/withverify/verifyWithinPerform.js",
    "content": "module.exports = {  \n  demoTest(client) {\n    client.url('http://localhost')\n      .verify.equal(0, 1, 'custom message')\n      .perform(function () {\n        client\n          .pause(1000)\n          .verify.containsText('#weblogin', 'first');\n\n      })\n      .end();\n  }\n};\n  "
  },
  {
    "path": "test/sampletests/withwait/elementNotPresent.js",
    "content": "module.exports = {\n  before(client) {\n    client.globals.calls++;\n  },\n  \n  demoTest(client) {\n    client.url('http://localhost')\n      .waitForElementNotPresent('#badElement')\n      .waitForElementNotPresent('#weblogin')\n      .end();\n  },\n\n  after(client, callback) {\n    client.globals.calls++;\n    callback();\n  }\n};\n  "
  },
  {
    "path": "test/sampletests/withwebdriver/sampleTestUsingSeleniumWebdriver.js",
    "content": "// Generated by Selenium IDE\nconst {Builder, By, logging} = require('selenium-webdriver');\nconst logger = logging.getLogger('webdriver.http');\nlogger.setLevel(logging.Level.FINER);\n\ndescribe('sampleTest with selenium-webdriver', function() {\n  this.timeout(30000);\n\n  this.settings.start_session = false;\n\n  let driver;\n\n  before(async () => {\n    const builder = new Builder().forBrowser('firefox').usingServer(this.settings.webdriver.url);\n    try {\n      driver = await builder.build();\n    } catch (err) {\n      console.error('ERROR', err);\n    }\n  });\n\n  after(async function() {\n    await driver.quit();\n  });\n\n  test('navigate', async function(nightwatch) {\n    await driver.get('http://localhost');\n  });\n\n  test('sampleTest', async function(nightwatch) {\n    const element = await driver.findElement(By.css('#weblogin'));\n    await expect(element).visible;\n    await nightwatch.assert.visible(element);\n\n    await element.click();\n  });\n});\n"
  },
  {
    "path": "test/src/analytics/testAnalytics.js",
    "content": "const assert = require('assert');\nconst fs = require('fs').promises;\nconst Nocks = require('../../lib/nocks.js');\nconst common = require('../../common.js');\nconst {Logger} = common.require('utils');\nlet analytics = common.require('utils/analytics.js');\nconst Settings = common.require('settings/settings.js');\n\nfunction requireUncached(module) {\n  delete require.cache[require.resolve(module)];\n\n  return require(module);\n}\n\ndescribe('test analytics utility', function() {\n  before(function() {\n    Logger.disable();\n    const settings = Settings.parse({\n      usage_analytics: {\n        enabled: true,\n        serverUrl: 'http://localhost:13555'\n      }\n    });\n    analytics.updateSettings(settings);\n  });\n\n  afterEach(async function() {\n    Nocks.cleanAll();\n    try {\n      const logfile = analytics.__getLogFileLocation();\n      await fs.stat(logfile);\n      await fs.unlink(logfile);\n    } catch (e) {\n      // Ignore\n    }\n  });\n\n  it('should throw error if event parameters contain objects or arrays', function() {\n    assert.rejects(async function() {\n      await analytics.collectEvent('test', {\n        foo: {\n          bar: 'bas'\n        }\n      });\n    });\n\n    assert.rejects(async function() {\n      await analytics.collectEvent('test', {\n        foo: [1, 2, 3]\n      });\n    });\n  });\n\n  it('should write events to a log file', async function() {\n    const flushFn = analytics.__flush;\n    let flushCalled = false;\n    analytics.__flush = function() {\n      flushCalled = true;\n    };\n\n    await analytics.collectEvent('test', {\n      foo: 'bar'\n    });\n    const logFile = analytics.__getLogFileLocation();\n\n    try {\n      const stats = await fs.stat(logFile);\n      assert.ok(stats.size > 0);\n      assert.ok(flushCalled);\n    } catch (e) {\n      assert.fail(e);\n    }\n\n    analytics.__flush = flushFn;\n  });\n\n  it('should have default parameters', async function() {\n    const flushFn = analytics.__flush;\n    let flushCalled = false;\n    analytics.__flush = function() {\n      flushCalled = true;\n    };\n\n    await analytics.collectEvent('test', {\n      foo: 'bar'\n    });\n\n    const logFile = analytics.__getLogFileLocation();\n    const logFileContent = await fs.readFile(logFile, 'utf8');\n\n    const logFileJson = JSON.parse(logFileContent);\n    assert.ok(logFileJson.params.foo === 'bar');\n    assert.ok(logFileJson.params.event_time);\n    assert.ok(logFileJson.params.env_os);\n    assert.ok(logFileJson.params.env_nw_version);\n    assert.ok(logFileJson.params.env_node_version);\n    assert.ok(flushCalled);\n\n    analytics.__flush = flushFn;\n  });\n\n  it('should send analytics data to GA', async function() {\n    const analyticsNock = Nocks.analyticsCollector(analytics.__getGoogleAnalyticsPath());\n\n    await analytics.collectEvent('test', {log: 'log'});\n\n    await analytics.__flush().then((res) => {\n      analyticsNock.done();\n    }).catch((err) => {\n      assert.strictEqual(err, undefined);\n    });\n  });\n\n  it('should flush queue after around 5 events', async function() {\n    Nocks.analyticsCollector(analytics.__getGoogleAnalyticsPath());\n\n    const flushBack = analytics.__flush;\n    \n    var called = false;\n    analytics.__flush = function() {\n      called = true;\n    };\n\n    await analytics.collectEvent('test', {log: 'log'});\n    await analytics.collectEvent('test', {log: 'log'});\n    await analytics.collectEvent('test', {log: 'log'});\n    await analytics.collectEvent('test', {log: 'log'});\n    await analytics.collectEvent('test', {log: 'log'});\n    await analytics.collectEvent('test', {log: 'log'});\n\n    assert.ok(called);\n    analytics.__flush = flushBack;\n\n    await analytics.__flush();\n  });\n\n  it('should flush queue after around 5 start up', async function() {\n    Nocks.analyticsCollector(analytics.__getGoogleAnalyticsPath());\n\n    const settings = Settings.parse({\n      usage_analytics: {\n        enabled: true,\n        serverUrl: 'http://localhost:13555'\n      }\n    });\n    \n    let flushBack = analytics.__flush;\n    var called = false;\n\n    for (let i = 0; i < 7; i++) {\n      analytics = requireUncached('../../../lib/utils/analytics.js');\n    \n      flushBack = analytics.__flush;\n      analytics.__flush = function() {\n        called = true;\n      };\n      analytics.updateSettings(settings);\n      await analytics.collectEvent('test', {log: 'log'});\n    }\n    \n    assert.ok(called);\n    analytics.__flush = flushBack;\n\n    await analytics.__flush();\n  });\n\n  it('should report only allowed exceptions', async function() {\n    const flushFn = analytics.__flush;\n    let flushCalled = false;\n    analytics.__flush = function() {\n      flushCalled = true;\n    };\n\n    const analyticsNock = Nocks.analyticsCollector(analytics.__getGoogleAnalyticsPath());\n    const err = new Error('test');\n    err.name = 'UserGeneratedError';\n\n    await analytics.collectErrorEvent(err);\n\n    assert.ok(flushCalled);\n    analytics.__flush = flushFn;\n\n    const logFile = analytics.__getLogFileLocation();\n    let logFileContent = await fs.readFile(logFile, 'utf8');\n    let logFileJson = JSON.parse(logFileContent);\n\n    assert.equal(logFileJson.params.err_name, 'UserGeneratedError');\n\n    await analytics.__flush().then((res) => {\n      analyticsNock.done();\n    }).catch((err) => {\n      assert.strictEqual(err, undefined);\n    });\n\n    const analyticsNock2 = Nocks.analyticsCollector(analytics.__getGoogleAnalyticsPath());\n    err.name = 'SyntaxError';\n\n    await analytics.collectErrorEvent(err);\n\n    logFileContent = await fs.readFile(logFile, 'utf8');\n    logFileJson = JSON.parse(logFileContent);\n\n    assert.equal(logFileJson.params.err_name, 'SyntaxError');\n\n    await analytics.__flush().then((res) => {\n      analyticsNock2.done();\n    }).catch((err) => {\n      assert.strictEqual(err, undefined);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testAttributeContains.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.attributeContains', function () {\n\n  const assertionName = 'attributeContains';\n  const api = 'getAttribute';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('attributeContains assertion passed', function() {\n    return assertionTest({\n      args: ['.test_element', 'href', 'google', 'Test message'],\n      commandResult: {\n        value: 'http://www.google.com'\n      },\n      assertArgs: true,\n      assertMessage: true,\n      assertion({reporter, instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('attributeContains assertion passed with backwards compat mode', function() {\n    return assertionTest({\n      args: ['.test_element', 'href', 'google', 'Test message'],\n      commandResult: {\n        value: 'http://www.google.com'\n      },\n      assertArgs: true,\n      assertMessage: true,\n      assertion({reporter, instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n      },\n      settings: {\n        backwards_compatibility_mode: true\n      }\n    });\n  });\n\n  it('not.attributeContains assertion passed with backwards compat mode', function() {\n    return assertionTest({\n      args: ['.test_element', 'href', 'google'],\n      commandResult: {\n        value: 'http://ecosia.org'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'http://ecosia.org');\n        assert.strictEqual(instance.getActual(), 'http://ecosia.org');\n        assert.strictEqual(instance.message, 'Testing if attribute \\'href\\' of element <.test_element> doesn\\'t contain \\'google\\'');\n        assert.ok(message.startsWith('Testing if attribute \\'href\\' of element <.test_element> doesn\\'t contain \\'google\\''), message);\n      },\n      settings: {\n        backwards_compatibility_mode: true\n      }\n    });\n  });\n\n  it('not.attributeContains assertion passed', function() {\n    return assertionTest({\n      args: ['.test_element', 'href', 'google'],\n      commandResult: {\n        value: 'http://ecosia.org'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'http://ecosia.org');\n        assert.strictEqual(instance.getActual(), 'http://ecosia.org');\n        assert.strictEqual(instance.message, 'Testing if attribute \\'href\\' of element <.test_element> doesn\\'t contain \\'google\\'');\n        assert.ok(message.startsWith('Testing if attribute \\'href\\' of element <.test_element> doesn\\'t contain \\'google\\''), message);\n      }\n    });\n  });\n\n  it('not.attributeContains assertion failed', function() {\n    return assertionTest({\n      args: ['.test_element', 'href', 'google'],\n      commandResult: {\n        value: 'http://google.org'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'http://google.org');\n        assert.strictEqual(instance.getActual(), 'http://google.org');\n        assert.strictEqual(err.message, `Testing if attribute 'href' of element <.test_element> doesn't contain 'google' in 5ms - expected \"not contains 'google'\" but got: \"http://google.org\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('attributeContains assertion passed with selector object', function() {\n    return assertionTest({\n      args: [{\n        selector: '.test_element'\n      }, 'href', 'google'],\n      commandResult: {\n        value: 'http://google.com'\n      },\n      assertArgs: true,\n      assertion({instance, failure, message}) {\n        assert.strictEqual(instance.message, 'Testing if attribute \\'href\\' of element <.test_element> contains \\'google\\'');\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.elementSelector, '<.test_element>');\n\n        assert.throws(function() {\n          instance.api = {};\n        }, /^Error: Attempting to override \"\\.api\" which is a reserved property in \"(.+)\"\\.$/);\n\n        assert.throws(function() {\n          instance.elementSelector = {};\n        }, /^Error: Attempting to override \"\\.elementSelector\" which is a reserved property in \"(.+)\"\\.$/);\n\n        assert.throws(function() {\n          instance.args = {};\n        }, /^Error: Attempting to override \"\\.args\" which is a reserved property in \"(.+)\"\\.$/);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getActual(), 'http://google.com');\n        assert.ok(message.startsWith('Testing if attribute \\'href\\' of element <.test_element> contains \\'google\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('attributeContains assertion failed', function() {\n    return assertionTest({\n      args: ['.test_element', 'role', 'whatever', 'Test message'],\n      commandResult: {\n        value: 'not_expected'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'not_expected');\n        assert.strictEqual(failure, 'Expected \"contains \\'whatever\\'\" but got: \"not_expected\"');\n      }\n    });\n  });\n\n  it('attributeContains assertion - element not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'role', 'main'],\n      commandResult: {\n        value: [],\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'contains \\'main\\'');\n        assert.strictEqual(failure, 'Expected \"contains \\'main\\'\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Testing if attribute 'role' of element <.test_element> contains 'main' in 5ms - expected \"contains 'main'\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('attributeContains assertion - attribute not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'role', 'main'],\n      commandResult: {\n        status: 0,\n        value: null\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(instance.getActual(), 'Element does not have a \\'role\\' attribute');\n        assert.strictEqual(err.message, `Testing if attribute 'role' of element <.test_element> contains 'main' in 5ms - expected \"contains 'main'\" but got: \"Element does not have a 'role' attribute\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.attributeContains assertion - attribute not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'role', 'main'],\n      commandResult: {\n        status: 0,\n        value: null\n      },\n      negate: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(instance.getActual(), 'Element does not have a \\'role\\' attribute');\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testAttributeEquals.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.attributeEquals', function () {\n  const assertionName = 'attributeEquals';\n  const api = 'getAttribute';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('attributeEquals assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'role', 'main', 'Test message'],\n      commandResult: {\n        value: 'main'\n      },\n      assertMessage: true,\n      assertArgs: true,\n      assertion({reporter, instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('not.attributeEquals assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'role', 'main'],\n      commandResult: {\n        value: 'second'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'second');\n        assert.strictEqual(instance.getActual(), 'second');\n        assert.strictEqual(instance.message, 'Testing if attribute \\'role\\' of element <.test_element> doesn\\'t equal \\'main\\'');\n        assert.ok(message.startsWith('Testing if attribute \\'role\\' of element <.test_element> doesn\\'t equal \\'main\\''), message);\n      }\n    });\n  });\n\n  it('not.attributeEquals assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'role', 'main'],\n      commandResult: {\n        value: 'main'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'main');\n        assert.strictEqual(instance.getActual(), 'main');\n        assert.strictEqual(err.message, `Testing if attribute 'role' of element <.test_element> doesn't equal 'main' in 5ms - expected \"not equals 'main'\" but got: \"main\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('attributeEquals assertion passed with selector object', function() {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'role', 'main'],\n      commandResult: {\n        value: 'main'\n      },\n      assertArgs: true,\n      assertResult: true,\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'main');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if attribute \\'role\\' of element <.test_element> equals \\'main\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('attributeEquals assertion failed', function() {\n    return assertionTest({\n      args: ['.test_element', 'role', 'main', 'Test message'],\n      commandResult: {\n        value: 'not_expected'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'not_expected');\n        assert.strictEqual(failure, 'Expected \"equals \\'main\\'\" but got: \"not_expected\"');\n      }\n    });\n  });\n\n  it('attributeEquals assertion - element not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'role', 'main', 'Test attribute %s from element \"%s\" == %s'],\n      commandResult: {\n        status: -1,\n        value: []\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'equals \\'main\\'');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"equals \\'main\\'\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Test attribute 'role' from element \"<.test_element>\" == 'main' in 5ms - expected \"equals 'main'\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('attributeEquals assertion - attribute not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'role', 'main'],\n      commandResult: {\n        status: 0,\n        value: null\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, message, failure}) {\n        assert.strictEqual(message, `Testing if attribute 'role' of element <.test_element> equals 'main' in 5ms - expected \"equals 'main'\" but got: \"Element does not have a 'role' attribute\" (${instance.elapsedTime}ms)`);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(instance.getActual(), 'Element does not have a \\'role\\' attribute');\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testAttributeMatches.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.attributeMatches', function () {\n  const assertionName = 'attributeMatches';\n  const api = 'getAttribute';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('attributeMatches assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'data-test', '(button)', 'Test message'],\n      assertMessage: true,\n      assertArgs: true,\n      assertResult: true,\n      commandResult: {\n        value: 'cta-button'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'cta-button');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('attributeMatches assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'data-test', '(button)'],\n      commandResult: {\n        value: 'random value'\n      },\n      assertError: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'random value');\n        assert.strictEqual(instance.expected(), 'matches \\'(button)\\'');\n        assert.strictEqual(instance.getValue(), 'random value');\n        assert.strictEqual(failure, 'Expected \"matches \\'(button)\\'\" but got: \"random value\"');\n        assert.strictEqual(err.message, `Testing if attribute 'data-test' of element <.test_element> matches '(button)' in 5ms - expected \"matches '(button)'\" but got: \"random value\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.attributeMatches assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'data-test', '(button)', 'Test message'],\n      commandResult: {\n        value: 'random value'\n      },\n      assertResult: true,\n      assertMessage: true,\n      assertArgs: true,\n      negate: true,\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'random value');\n        assert.strictEqual(instance.message, 'Test message');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.attributeMatches assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'data-test', '(button)'],\n      commandResult: {\n        value: 'test-button'\n      },\n      assertResult: true,\n      negate: true,\n      assertError: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, 'Expected \"does not matches \\'(button)\\'\" but got: \"test-button\"');\n        assert.strictEqual(instance.getActual(), 'test-button');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testContainsText.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.containsText', function () {\n  const assertionName = 'containsText';\n  const api = 'getText';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('containsText assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text result', 'Test message'],\n      commandResult: {\n        value: 'expected text result'\n      },\n      assertArgs: true,\n      assertMessage: true,\n      assertion({reporter, instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getValue(), 'expected text result');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('not.containsText assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text result', 'Test message'],\n      commandResult: {\n        value: 'other text'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other text');\n        assert.strictEqual(instance.getActual(), 'does not contain \\'text result\\'');\n        assert.strictEqual(instance.message, 'Test message');\n      }\n    });\n  });\n\n  it('not.containsText assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text result', 'Test message'],\n      commandResult: {\n        value: 'expected text result'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'expected text result');\n        assert.strictEqual(instance.getActual(), 'contains \\'text result\\'');\n        assert.strictEqual(err.message, `Test message in 5ms - expected \"does not contain text 'text result'\" but got: \"contains 'text result'\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('containsText assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'text result'],\n      commandResult: {\n        value: 'expected text result'\n      },\n      assertArgs: true,\n      assertResult: true,\n      assertion({instance, failure, message, err}) {\n        assert.ok(message.startsWith('Testing if element <.test_element> contains text \\'text result\\''), message);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'contains \\'text result\\'');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if element <.test_element> contains text \\'text result\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('containsText assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text result', 'Test message'],\n      commandResult: {\n        value: 'not_expected'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'does not contain \\'text result\\'');\n        assert.strictEqual(failure, 'Expected \"contains text \\'text result\\'\" but got: \"does not contain \\'text result\\'\"');\n      }\n    });\n  });\n\n  it('containsText assertion - element not found', function () {\n    return assertionTest({\n      args: ['.test_element', 'text result', 'Test message'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'contains text \\'text result\\'');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"contains text \\'text result\\'\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Test message in 5ms - expected \"contains text 'text result'\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/assertions/testCssClassPresent.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.cssClassPresent', function () {\n  const assertionName = 'cssClassPresent';\n  const api = 'getAttribute';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('cssClassPresent assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class'],\n      commandResult: {\n        value: 'other-css-class test-css-class'\n      },\n      assertResult: true,\n      assertApiCommandArgs(args) {\n        assert.deepStrictEqual(args[0], {\n          selector: '.test_element',\n          suppressNotFoundErrors: true\n        });\n        assert.strictEqual(args[1], 'class');\n        assert.strictEqual(typeof args[2], 'function');\n      },\n      assertion({reporter, instance, queueOpts, failure, message}) {\n        assert.deepStrictEqual(instance.args, ['.test_element', 'test-css-class']);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-css-class test-css-class');\n        assert.ok(message.startsWith('Testing if element <.test_element> has css class \\'test-css-class\\''), message);\n      }\n    });\n  });\n\n  it('cssClassPresent assertion passed - multiple values array', function () {\n    return assertionTest({\n      args: ['.test_element', ['test-css-class', 'other-css-class']],\n      commandResult: {\n        value: 'other-css-class test-css-class'\n      },\n      assertResult: true,\n      assertApiCommandArgs(args) {\n        assert.deepStrictEqual(args[0], {\n          selector: '.test_element',\n          suppressNotFoundErrors: true\n        });\n        assert.strictEqual(args[1], 'class');\n        assert.strictEqual(typeof args[2], 'function');\n      },\n      assertion({reporter, instance, queueOpts, failure, message}) {\n        assert.deepStrictEqual(instance.args, ['.test_element', ['test-css-class', 'other-css-class']]);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-css-class test-css-class');\n        assert.ok(message.startsWith('Testing if element <.test_element> has css class \\'test-css-class other-css-class\\''), message);\n      }\n    });\n  });\n\n  it('cssClassPresent assertion passed - multiple values string', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class other-css-class'],\n      commandResult: {\n        value: 'other-css-class test-css-class'\n      },\n      assertResult: true,\n      assertApiCommandArgs(args) {\n        assert.deepStrictEqual(args[0], {\n          selector: '.test_element',\n          suppressNotFoundErrors: true\n        });\n        assert.strictEqual(args[1], 'class');\n        assert.strictEqual(typeof args[2], 'function');\n      },\n      assertion({reporter, instance, queueOpts, failure, message}) {\n        assert.deepStrictEqual(instance.args, ['.test_element', 'test-css-class other-css-class']);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-css-class test-css-class');\n        assert.ok(message.startsWith('Testing if element <.test_element> has css class \\'test-css-class other-css-class\\''), message);\n      }\n    });\n  });\n\n  it('not.cssClassPresent assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class'],\n      commandResult: {\n        value: 'other-css-class'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-css-class');\n        assert.strictEqual(instance.getActual(), 'other-css-class');\n        assert.strictEqual(instance.message, 'Testing if element <.test_element> doesn\\'t have css class \\'test-css-class\\'');\n        assert.ok(message.startsWith('Testing if element <.test_element> doesn\\'t have css class \\'test-css-class\\''), message);\n      }\n    });\n  });\n\n  it('.not.cssClassPresent assertion passed - multiple values string', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class other-css-class'],\n      commandResult: {\n        value: 'other-css-class'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, failure, message}) {\n        assert.deepStrictEqual(instance.args, ['.test_element', 'test-css-class other-css-class']);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-css-class');\n        assert.ok(message.startsWith('Testing if element <.test_element> doesn\\'t have css class \\'test-css-class other-css-class\\''), message);\n      }\n    });\n  });\n\n  it('not.cssClassPresent assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class'],\n      commandResult: {\n        value: 'test-css-class other'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'test-css-class other');\n        assert.strictEqual(instance.getActual(), 'test-css-class other');\n        assert.strictEqual(instance.message, 'Testing if element <.test_element> doesn\\'t have css class \\'test-css-class\\'');\n        assert.ok(message.startsWith('Testing if element <.test_element> doesn\\'t have css class \\'test-css-class\\''), message);\n      }\n    });\n  });\n\n  it('not.cssClassPresent assertion failed - multiple classes', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class other'],\n      commandResult: {\n        value: 'other test-css-class'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other test-css-class');\n        assert.strictEqual(instance.getActual(), 'other test-css-class');\n        assert.strictEqual(instance.message, 'Testing if element <.test_element> doesn\\'t have css class \\'test-css-class other\\'');\n        assert.ok(message.startsWith('Testing if element <.test_element> doesn\\'t have css class \\'test-css-class other\\' in 5ms - expected \"has not test-css-class other\" but got: \"other test-css-class\"'), message);\n      }\n    });\n  });\n\n  it('cssClassPresent assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'test-css-class'],\n      commandResult: {\n        value: 'other-css-class test-css-class'\n      },\n      assertResult: true,\n      assertApiCommandArgs(args) {\n        assert.deepStrictEqual(args[0], {selector: '.test_element', suppressNotFoundErrors: true});\n        assert.strictEqual(args[1], 'class');\n        assert.strictEqual(typeof args[2], 'function');\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'other-css-class test-css-class');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if element <.test_element> has css class \\'test-css-class\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('cssClassPresent assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class'],\n      commandResult: {\n        value: 'other-css-class'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'other-css-class');\n        assert.strictEqual(failure, 'Expected \"has test-css-class\" but got: \"other-css-class\"');\n      }\n    });\n  });\n\n  it('cssClassPresent assertion - element not found', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class', 'Element %s doesnt have css class \"%s\"'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'has test-css-class');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"has test-css-class\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Element <.test_element> doesnt have css class \"'test-css-class'\" in 5ms - expected \"has test-css-class\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testCssProperty.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.cssProperty', function () {\n  const assertionName = 'cssProperty';\n  const api = 'getCssProperty';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('cssProperty assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'display', 'none'],\n      commandResult: {\n        value: 'none'\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, message}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if element <.test_element> has css property \\'display: none\\''), message);\n      }\n    });\n  });\n\n  it('not.cssProperty assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'display', 'none'],\n      commandResult: {\n        value: 'second'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'second');\n        assert.strictEqual(instance.getActual(), 'second');\n        assert.strictEqual(instance.message, 'Testing if element <.test_element> doesn\\'t have css property \\'display: none\\'');\n        assert.ok(message.startsWith('Testing if element <.test_element> doesn\\'t have css property \\'display: none\\''), message);\n      }\n    });\n  });\n\n  it('not.cssProperty assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'display', 'none'],\n      commandResult: {\n        value: 'none'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'none');\n        assert.strictEqual(instance.getActual(), 'none');\n        assert.strictEqual(err.message, `Testing if element <.test_element> doesn't have css property 'display: none' in 5ms - expected \"not none\" but got: \"none\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('cssProperty assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'display', 'none'],\n      commandResult: {\n        value: 'none'\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'none');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if element <.test_element> has css property \\'display: none\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('cssProperty assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'display', 'none', 'Test message'],\n      commandResult: {\n        value: 'not_expected'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'not_expected');\n        assert.strictEqual(failure, 'Expected \"none\" but got: \"not_expected\"');\n      }\n    });\n  });\n\n  it('cssProperty assertion - element not found', function () {\n    return assertionTest({\n      args: ['.test_element', 'display', 'none', 'Test attribute %s from element \"%s\" == %s'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'none');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"none\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Test attribute <.test_element> from element \"'display\" == none' in 5ms - expected \"none\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('attributeEquals assertion - css property not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'display', 'none'],\n      commandResult: {\n        status: 0,\n        value: null\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, message, failure}) {\n        assert.strictEqual(message, `Testing if element <.test_element> has css property 'display: none' in 5ms - expected \"none\" but got: \"Element does not have a 'display' css property\" (${instance.elapsedTime}ms)`);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(instance.getActual(), 'Element does not have a \\'display\\' css property');\n      }\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/assertions/testDomPropertyContains.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.domPropertyEquals', function () {\n  const assertionName = 'domPropertyContains';\n  const api = 'getElementProperty';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('domPropertyContains assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element'],\n      commandResult: {\n        value: 'visible-element'\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, message, err}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(err, undefined);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'className\\' of element <.test_element> contains \\'visible-element\\''), message);\n      }\n    });\n  });\n\n  it('domPropertyContains assertion passed - array result', function () {\n    return assertionTest({\n      args: ['.test_element', 'classList', ['visible-element']],\n      commandResult: {\n        value: ['visible-element']\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, message, err}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(err, undefined);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'classList\\' of element <.test_element> contains \\'[\"visible-element\"]\\''), message);\n      }\n    });\n  });\n\n  it('domPropertyContains assertion passed - array result and string argument', function () {\n    return assertionTest({\n      args: ['.test_element', 'classList', 'visible-element'],\n      commandResult: {\n        value: ['visible-element']\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, message, err}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(err, undefined);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'classList\\' of element <.test_element> contains \\'visible-element\\''), message);\n      }\n    });\n  });\n\n  it('domPropertyContains assertion passed - array result and multiple string argument', function () {\n    return assertionTest({\n      args: ['.test_element', 'classList', 'visible,element'],\n      commandResult: {\n        value: ['visible', 'element']\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, message, err}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(err, undefined);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'classList\\' of element <.test_element> contains \\'visible,element\\''), message);\n      }\n    });\n  });\n\n  it('not.domPropertyContains assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element'],\n      commandResult: {\n        value: 'other-classname'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-classname');\n        assert.strictEqual(instance.getActual(), 'other-classname');\n        assert.strictEqual(instance.message, 'Testing if dom property \\'className\\' of element <.test_element> doesn\\'t contain \\'visible-element\\'');\n        assert.ok(message.startsWith('Testing if dom property \\'className\\' of element <.test_element> doesn\\'t contain \\'visible-element\\''), message);\n      }\n    });\n  });\n\n  it('not.domPropertyContains assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element'],\n      commandResult: {\n        value: 'visible-element'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'visible-element');\n        assert.strictEqual(instance.getActual(), 'visible-element');\n        assert.strictEqual(err.message, `Testing if dom property 'className' of element <.test_element> doesn't contain 'visible-element' in 5ms - expected \"not contains 'visible-element'\" but got: \"visible-element\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('domPropertyContains assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'className', 'visible-element'],\n      commandResult: {\n        value: 'visible-element'\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'visible-element');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'className\\' of element <.test_element> contains \\'visible-element\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('domPropertyContains assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element', 'Test message'],\n      commandResult: {\n        value: 'not_expected'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'not_expected');\n        assert.strictEqual(failure, 'Expected \"contains \\'visible-element\\'\" but got: \"not_expected\"');\n      }\n    });\n  });\n\n  it('domPropertyContains assertion - element not found', function () {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element', 'Test attribute %s from element \"%s\" == %s'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'contains \\'visible-element\\'');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"contains \\'visible-element\\'\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Test attribute 'className' from element \"<.test_element>\" == 'visible-element' in 5ms - expected \"contains 'visible-element'\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('domPropertyContains assertion - dom property not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element'],\n      commandResult: {\n        status: 0,\n        value: null\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, message, failure}) {\n        assert.strictEqual(message, `Testing if dom property 'className' of element <.test_element> contains 'visible-element' in 5ms - expected \"contains 'visible-element'\" but got: \"Element does not have a 'className' dom property\" (${instance.elapsedTime}ms)`);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(instance.getActual(), 'Element does not have a \\'className\\' dom property');\n      }\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/assertions/testDomPropertyEquals.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.domPropertyEquals', function () {\n  const assertionName = 'domPropertyEquals';\n  const api = 'getElementProperty';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('domPropertyEquals assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element'],\n      commandResult: {\n        value: 'visible-element'\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, message}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'className\\' of element <.test_element> equals \\'visible-element\\''), message);\n      }\n    });\n  });\n\n  it('domPropertyEquals assertion passed - array result', function () {\n    return assertionTest({\n      args: ['.test_element', 'classList', ['visible-element']],\n      commandResult: {\n        value: ['visible-element']\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, message}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'classList\\' of element <.test_element> equals \\'[\"visible-element\"]\\''), message);\n      }\n    });\n  });\n\n  it('domPropertyEquals assertion passed - object result', function () {\n    return assertionTest({\n      args: ['.test_element', 'domProp', {result: 'some-value'}],\n      commandResult: {\n        value: {result: 'some-value'}\n      },\n      assertion({reporter, instance, failure, err, message}) {\n        assert.strictEqual(err, undefined);\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'domProp\\' of element <.test_element> equals \\'{\"result\":\"some-value\"}\\''), message);\n      }\n    });\n  });\n\n  it('domPropertyEquals assertion failed - object result with circular reference', function () {\n    return assertionTest({\n      args: ['.test_element', 'domProp', {result: global}],\n      commandResult: {\n        value: {result: 'some-value'}\n      },\n      assertError: true,\n      assertion({reporter, instance, failure, err, message}) {\n        assert.strictEqual(failure, 'Expected \"[object Object]\" but got: \"[object Object]\"');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.includes('TypeError Converting circular structure to JSON'), message);\n      }\n    });\n  });\n\n  it('domPropertyEquals assertion passed - array result and string argument', function () {\n    return assertionTest({\n      args: ['.test_element', 'classList', 'visible-element'],\n      commandResult: {\n        value: ['visible-element']\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, message}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'classList\\' of element <.test_element> equals \\'visible-element\\''), message);\n      }\n    });\n  });\n\n  it('domPropertyEquals assertion passed - array result and string argument with comma-separated values', function () {\n    return assertionTest({\n      args: ['.test_element', 'classList', 'visible,element'],\n      commandResult: {\n        value: ['visible', 'element']\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, message}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'classList\\' of element <.test_element> equals \\'visible,element\\''), message);\n      }\n    });\n  });\n\n  it('not.domPropertyEquals assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element'],\n      commandResult: {\n        value: 'other-classname'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-classname');\n        assert.strictEqual(instance.getActual(), 'other-classname');\n        assert.strictEqual(instance.message, 'Testing if dom property \\'className\\' of element <.test_element> doesn\\'t equal \\'visible-element\\'');\n        assert.ok(message.startsWith('Testing if dom property \\'className\\' of element <.test_element> doesn\\'t equal \\'visible-element\\''), message);\n      }\n    });\n  });\n\n  it('not.domPropertyEquals assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element'],\n      commandResult: {\n        value: 'visible-element'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'visible-element');\n        assert.strictEqual(instance.getActual(), 'visible-element');\n        assert.strictEqual(err.message, `Testing if dom property 'className' of element <.test_element> doesn't equal 'visible-element' in 5ms - expected \"not visible-element\" but got: \"visible-element\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('domPropertyEquals assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'className', 'visible-element'],\n      commandResult: {\n        value: 'visible-element'\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'visible-element');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if dom property \\'className\\' of element <.test_element> equals \\'visible-element\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('domPropertyEquals assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element', 'Test message'],\n      commandResult: {\n        value: 'not_expected'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'not_expected');\n        assert.strictEqual(failure, 'Expected \"visible-element\" but got: \"not_expected\"');\n      }\n    });\n  });\n\n  it('domPropertyEquals assertion - element not found', function () {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element', 'Test attribute %s from element \"%s\" == %s'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'visible-element');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"visible-element\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Test attribute 'className' from element \"<.test_element>\" == 'visible-element' in 5ms - expected \"visible-element\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('domPropertyEquals assertion - dom property not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'className', 'visible-element'],\n      commandResult: {\n        status: 0,\n        value: null\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, message, failure}) {\n        assert.strictEqual(message, `Testing if dom property 'className' of element <.test_element> equals 'visible-element' in 5ms - expected \"visible-element\" but got: \"Element does not have a 'className' dom property\" (${instance.elapsedTime}ms)`);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(instance.getActual(), 'Element does not have a \\'className\\' dom property');\n      }\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/assertions/testDomPropertyMatches.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.domPropertyMatches', function () {\n  const assertionName = 'domPropertyMatches';\n  const api = 'getElementProperty';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('domPropertyMatches assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'tagName', 'test', 'Test message'],\n      assertMessage: true,\n      assertArgs: true,\n      assertResult: true,\n      commandResult: {\n        value: 'test'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'test');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('domPropertyMatches assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'tagName', 'test'],\n      commandResult: {\n        value: 'random_tag'\n      },\n      assertError: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'random_tag');\n        assert.strictEqual(instance.expected(), 'matches \\'test\\'');\n        assert.strictEqual(instance.getValue(), 'random_tag');\n        assert.strictEqual(failure, 'Expected \"matches \\'test\\'\" but got: \"random_tag\"');\n        assert.strictEqual(err.message, `Testing if dom property 'tagName' of element <.test_element> matches 'test' in 5ms - expected \"matches 'test'\" but got: \"random_tag\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.domPropertyMatches assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'tagName', 'test', 'Test message'],\n      commandResult: {\n        value: 'random_tag'\n      },\n      assertResult: true,\n      assertMessage: true,\n      assertArgs: true,\n      negate: true,\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'random_tag');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.domPropertyMatches assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'tagName', 'test'],\n      commandResult: {\n        value: 'test'\n      },\n      assertResult: true,\n      negate: true,\n      assertError: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, 'Expected \"does not matches \\'test\\'\" but got: \"test\"');\n        assert.strictEqual(instance.getActual(), 'test');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testElementPresent.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.elementPresent', function() {\n  const assertionName = 'elementPresent';\n  const api = 'elements';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('elementPresent assertion passed', function() {\n    return assertionTest({\n      args: ['.test_element', 'Test message'],\n      commandResult: {\n        status: 0,\n        value: [{\n          ELEMENT: '0'\n        }]\n      },\n      assertMessage: true,\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args[0], 'css selector');\n        assert.strictEqual(typeof args[1], 'object');\n        assert.strictEqual(args[1].toString(), '.test_element');\n        assert.strictEqual(typeof args[2], 'function');\n      },\n      assertion({reporter, instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('not.elementPresent assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        value: []\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'not present');\n        assert.strictEqual(instance.getActual(), 'not present');\n        assert.strictEqual(instance.message, 'Testing if element <.test_element> is not present');\n        assert.ok(message.startsWith('Testing if element <.test_element> is not present'), message);\n      }\n    });\n  });\n\n  it('not.elementPresent assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        value: [{\n          ELEMENT: '0'\n        }]\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'present');\n        assert.strictEqual(instance.getActual(), 'present');\n        assert.strictEqual(err.message, `Testing if element <.test_element> is not present in 5ms - expected \"is not present\" but got: \"present\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('elementPresent assertion passed with selector object', function() {\n    return assertionTest({\n      args: [{selector: '.test_element'}],\n      commandResult: {\n        status: 0,\n        value: [{\n          ELEMENT: '0'\n        }]\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args[0], 'css selector');\n        assert.strictEqual(typeof args[1], 'object');\n        assert.strictEqual(args[1].toString(), '.test_element');\n        assert.strictEqual(typeof args[2], 'function');\n      },\n\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'present');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if element <.test_element> is present'), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('elementPresent assertion passed - with W3C Webdriver', function() {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        value: [{'element-6066-11e4-a52e-4f735466cecf': 'b8461b6b-7c4b-ac46-8b1a-7071c3b111f1'}]\n      },\n      assertion({instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('elementPresent assertion failed', function() {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: 0,\n        value: []\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'not present');\n        assert.strictEqual(failure, 'Expected \"is present\" but got: \"not present\"');\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testElementsCount.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.elementCounts', function () {\n  const assertionName = 'elementsCount';\n  const api = 'findElements';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('elementsCount assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 2, 'Test message'],\n      commandResult: {\n        value: [{'ELEMENT': '0'}, {'ELEMENT': '1'}]\n      },\n      assertMessage: true,\n      assertion({instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.message, 'Test message');\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('not.elementsCount assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 2],\n      commandResult: {\n        value: [{'ELEMENT': '0'}]\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 1);\n        assert.strictEqual(instance.getActual(), 1);\n        assert.strictEqual(instance.message, 'Testing if the element count for <.test_element> is not 2');\n        assert.ok(message.startsWith('Testing if the element count for <.test_element> is not 2'), message);\n      }\n    });\n  });\n\n\n  it('elementsCount assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 1],\n      commandResult: {\n        value: [{'ELEMENT': '0'}, {'ELEMENT': '1'}]\n      },\n      negate: false,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 2);\n        assert.strictEqual(instance.getActual(), 2);\n        assert.strictEqual(err.message, `Testing if the element count for <.test_element> is 1 in 5ms - expected \"counts 1\" but got: \"2\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('not.elementsCount assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 2],\n      commandResult: {\n        value: [{'ELEMENT': '0'}, {'ELEMENT': '1'}]\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 2);\n        assert.strictEqual(instance.getActual(), 2);\n        assert.strictEqual(err.message, `Testing if the element count for <.test_element> is not 2 in 5ms - expected \"does not count 2\" but got: \"2\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('elementCounts assertion passed with selector object', function() {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 1],\n      commandResult: {\n        value: [{'ELEMENT': 0}]\n      },\n      assertArgs: true,\n      assertResult: true,\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 1);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if the element count for <.test_element> is 1'), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('elementsCount assertion failed', function() {\n    return assertionTest({\n      args: ['.test_element', 2, 'Test message expected element %s to have count %s'],\n      commandResult: {\n        value: [{'ELMENT': 1}]\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 1);\n        assert.strictEqual(instance.message, 'Test message expected element <.test_element> to have count 2');\n        assert.strictEqual(failure, 'Expected \"counts 2\" but got: \"1\"');\n      }\n    });\n  });\n\n  it('elementsCount assertion - no elements found', function() {\n    return assertionTest({\n      args: ['.test_element', 2],\n      commandResult: {\n        status: 0,\n        value: []\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, message, failure}) {\n        assert.strictEqual(message, `Testing if the element count for <.test_element> is 2 in 5ms - expected \"counts 2\" but got: \"0\" (${instance.elapsedTime}ms)`);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 0);\n        assert.strictEqual(instance.getActual(), 0);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testEnabled.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.enabled', function () {\n  const assertionName = 'enabled';\n  const api = 'isEnabled';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('enabled assertion passed', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'Test message'],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      assertArgs: true,\n      assertMessage: true,\n      assertion({reporter, instance, failure, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.enabled assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: 0,\n        value: false\n      },\n      negate: true,\n\n      assertion({reporter, instance, queueOpts, err, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), false);\n        assert.strictEqual(instance.getActual(), 'not enabled');\n        assert.strictEqual(\n          instance.message,\n          'Testing if element <.test_element> is not enabled'\n        );\n        assert.ok(\n          message.startsWith(\n            'Testing if element <.test_element> is not enabled'\n          ),\n          message\n        );\n      }\n    });\n  });\n\n  it('.not.enabled assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      negate: true,\n      assertError: true,\n\n      assertion({reporter, instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), true);\n        assert.strictEqual(instance.getActual(), 'enabled');\n        assert.strictEqual(\n          err.message,\n          `Testing if element <.test_element> is not enabled in 5ms - expected \"is not enabled\" but got: \"enabled\" (${instance.elapsedTime}ms)`\n        );\n      }\n    });\n  });\n\n  it('enabled assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'enabled');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(\n          message.startsWith('Testing if element <.test_element> is enabled'),\n          message\n        );\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('enabled assertion passed with selector object and timeout', function () {\n    return assertionTest({\n      args: [{selector: '.test_element', timeout: 10, retryInterval: 15}],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'enabled');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.retryAssertionTimeout, 10);\n        assert.strictEqual(instance.rescheduleInterval, 15);\n        assert.ok(\n          message.startsWith('Testing if element <.test_element> is enabled'),\n          message\n        );\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('enabled assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: 0,\n        value: false\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'not enabled');\n        assert.strictEqual(\n          failure,\n          'Expected \"is enabled\" but got: \"not enabled\"'\n        );\n      }\n    });\n  });\n\n  it('enabled assertion not - element not found', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(\n          instance.getActual(),\n          'element could not be located'\n        );\n        assert.strictEqual(instance.expected(), 'is enabled');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(\n          failure,\n          'Expected \"is enabled\" but got: \"element could not be located\"'\n        );\n        assert.strictEqual(\n          err.message,\n          `Testing if element <.test_element> is enabled in 5ms - expected \"is enabled\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`\n        );\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testHasAttribute.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.hasAttribute', function () {\n  const assertionName = 'hasAttribute';\n  const api = 'getAttribute';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('hasAttribute assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'data-test', 'Test message'],\n      commandResult: {\n        value: 'data-track'\n      },\n      assertMessage: true,\n      assertion({instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('not.hasAttribute assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'data-test'],\n      commandResult: {\n        value: 'data-track'\n      },\n      negate: true,\n      assertion({instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.deepStrictEqual(instance.getValue(), 'data-track');\n        assert.deepStrictEqual(instance.getActual(), 'data-track');\n        assert.strictEqual(instance.message, 'Testing if element <.test_element> doesn\\'t have attribute \\'data-test\\'');\n        assert.ok(message.startsWith('Testing if element <.test_element> doesn\\'t have attribute \\'data-test\\''), message);\n      }\n    });\n  });\n\n  it('not.hasAttribute assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'data-test'],\n      commandResult: {\n        value: 'data-test'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.deepStrictEqual(instance.getValue(), 'data-test');\n        assert.deepStrictEqual(instance.getActual(), 'data-test');\n        assert.strictEqual(err.message, `Testing if element <.test_element> doesn't have attribute 'data-test' in 5ms - expected \"has not data-test\" but got: \"data-test\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('hasAttribute assertion passed with selector object', function() {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'data-test'],\n      commandResult: {\n        value: 'data-test'\n      },\n      assertResult: true,\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.deepStrictEqual(instance.getActual(), 'data-test');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if element <.test_element> has attribute \\'data-test\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('hasAttribute assertion failed', function() {\n    return assertionTest({\n      args: ['.test_element', 'data-test', 'Test message'],\n      commandResult: {\n        value: null\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.deepStrictEqual(instance.getActual(), null);\n        assert.strictEqual(failure, 'Expected \"has data-test\" but got: \"null\"');\n      }\n    });\n  });\n\n  it('hasAttribute assertion - attribute not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'data-test'],\n      commandResult: {\n        status: 0,\n        value: ''\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, message, failure}) {\n        assert.strictEqual(message, `Testing if element <.test_element> has attribute 'data-test' in 5ms - expected \"has data-test\" but got: \"\" (${instance.elapsedTime}ms)`);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), '');\n        assert.strictEqual(instance.getActual(), '');\n      }\n    });\n  });\n\n  it('hasAttribute assertion failed for wrong parameters', function () {\n    return assertionTest({\n      args: ['.test_element', ['data-test', 'dummy'], 'Test message'],\n      commandResult: {\n        value: 'data-track'\n      },\n      assertMessage: true\n    }).catch((err) => {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.message, 'Error while running \"assert.hasAttribute\" command: Expected attribute must be a string');\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testHasClass.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.hasClass', function () {\n  const assertionName = 'hasClass';\n  const api = 'getAttribute';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('hasClass assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class'],\n      commandResult: {\n        value: 'other-css-class test-css-class'\n      },\n      assertResult: true,\n      assertApiCommandArgs(args) {\n        assert.deepStrictEqual(args[0], {\n          selector: '.test_element',\n          suppressNotFoundErrors: true\n        });\n        assert.strictEqual(args[1], 'class');\n        assert.strictEqual(typeof args[2], 'function');\n      },\n      assertion({reporter, instance, queueOpts, failure, message}) {\n        assert.deepStrictEqual(instance.args, ['.test_element', 'test-css-class']);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-css-class test-css-class');\n        assert.ok(message.startsWith('Testing if element <.test_element> has css class \\'test-css-class\\''), message);\n      }\n    });\n  });\n\n  it('hasClass assertion passed - multiple values array', function () {\n    return assertionTest({\n      args: ['.test_element', ['test-css-class', 'other-css-class']],\n      commandResult: {\n        value: 'other-css-class test-css-class'\n      },\n      assertResult: true,\n      assertApiCommandArgs(args) {\n        assert.deepStrictEqual(args[0], {\n          selector: '.test_element',\n          suppressNotFoundErrors: true\n        });\n        assert.strictEqual(args[1], 'class');\n        assert.strictEqual(typeof args[2], 'function');\n      },\n      assertion({reporter, instance, queueOpts, failure, message}) {\n        assert.deepStrictEqual(instance.args, ['.test_element', ['test-css-class', 'other-css-class']]);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-css-class test-css-class');\n        assert.ok(message.startsWith('Testing if element <.test_element> has css class \\'test-css-class other-css-class\\''), message);\n      }\n    });\n  });\n\n  it('hasClass assertion passed - multiple values string', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class other-css-class'],\n      commandResult: {\n        value: 'other-css-class test-css-class'\n      },\n      assertResult: true,\n      assertApiCommandArgs(args) {\n        assert.deepStrictEqual(args[0], {\n          selector: '.test_element',\n          suppressNotFoundErrors: true\n        });\n        assert.strictEqual(args[1], 'class');\n        assert.strictEqual(typeof args[2], 'function');\n      },\n      assertion({reporter, instance, queueOpts, failure, message}) {\n        assert.deepStrictEqual(instance.args, ['.test_element', 'test-css-class other-css-class']);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-css-class test-css-class');\n        assert.ok(message.startsWith('Testing if element <.test_element> has css class \\'test-css-class other-css-class\\''), message);\n      }\n    });\n  });\n\n  it('not.hasClass assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class'],\n      commandResult: {\n        value: 'other-css-class'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-css-class');\n        assert.strictEqual(instance.getActual(), 'other-css-class');\n        assert.strictEqual(instance.message, 'Testing if element <.test_element> doesn\\'t have css class \\'test-css-class\\'');\n        assert.ok(message.startsWith('Testing if element <.test_element> doesn\\'t have css class \\'test-css-class\\''), message);\n      }\n    });\n  });\n\n  it('.not.hasClass assertion passed - multiple values string', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class other-css-class'],\n      commandResult: {\n        value: 'other-css-class'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, failure, message}) {\n        assert.deepStrictEqual(instance.args, ['.test_element', 'test-css-class other-css-class']);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other-css-class');\n        assert.ok(message.startsWith('Testing if element <.test_element> doesn\\'t have css class \\'test-css-class other-css-class\\''), message);\n      }\n    });\n  });\n\n  it('not.hasClass assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class'],\n      commandResult: {\n        value: 'test-css-class other'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'test-css-class other');\n        assert.strictEqual(instance.getActual(), 'test-css-class other');\n        assert.strictEqual(instance.message, 'Testing if element <.test_element> doesn\\'t have css class \\'test-css-class\\'');\n        assert.ok(message.startsWith('Testing if element <.test_element> doesn\\'t have css class \\'test-css-class\\''), message);\n      }\n    });\n  });\n\n  it('not.hasClass assertion failed - multiple classes', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class other'],\n      commandResult: {\n        value: 'other test-css-class'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other test-css-class');\n        assert.strictEqual(instance.getActual(), 'other test-css-class');\n        assert.strictEqual(instance.message, 'Testing if element <.test_element> doesn\\'t have css class \\'test-css-class other\\'');\n        assert.ok(message.startsWith('Testing if element <.test_element> doesn\\'t have css class \\'test-css-class other\\' in 5ms - expected \"has not test-css-class other\" but got: \"other test-css-class\"'), message);\n      }\n    });\n  });\n\n  it('hasClass assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'test-css-class'],\n      commandResult: {\n        value: 'other-css-class test-css-class'\n      },\n      assertResult: true,\n      assertApiCommandArgs(args) {\n        assert.deepStrictEqual(args[0], {selector: '.test_element', suppressNotFoundErrors: true});\n        assert.strictEqual(args[1], 'class');\n        assert.strictEqual(typeof args[2], 'function');\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'other-css-class test-css-class');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if element <.test_element> has css class \\'test-css-class\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('hasClass assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class'],\n      commandResult: {\n        value: 'other-css-class'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'other-css-class');\n        assert.strictEqual(failure, 'Expected \"has test-css-class\" but got: \"other-css-class\"');\n      }\n    });\n  });\n\n  it('hasClass assertion - element not found', function () {\n    return assertionTest({\n      args: ['.test_element', 'test-css-class', 'Element %s doesnt have css class \"%s\"'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'has test-css-class');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"has test-css-class\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Element <.test_element> doesnt have css class \"'test-css-class'\" in 5ms - expected \"has test-css-class\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testHidden.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.hidden', function () {\n  const assertionName = 'hidden';\n  const api = 'isVisible';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('hidden assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'Test message'],\n      assertMessage: true,\n      assertArgs: true,\n      commandResult: {\n        status: 0,\n        value: false\n      },\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('hidden assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}],\n      commandResult: {\n        status: 0,\n        value: false\n      },\n      assertArgs: true,\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.strictEqual(instance.getActual(), true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if element \\'<.test_element>\\' is hidden'), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('hidden assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      assertArgs: true,\n      assertResult: true,\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), false);\n        assert.strictEqual(failure, 'Expected \"true\" but got: \"false\"');\n      }\n    });\n  });\n\n  it('hidden assertion - element not found', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), '');\n        assert.strictEqual(instance.expected, true);\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"true\" but got: \"\"');\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testSelected.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.selected', function () {\n  const assertionName = 'selected';\n  const api = 'isSelected';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('selected assertion passed', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'Test message'],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      assertArgs: true,\n      assertMessage: true,\n      assertion({reporter, instance, failure, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.selected assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: 0,\n        value: false\n      },\n      negate: true,\n\n      assertion({reporter, instance, queueOpts, err, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), false);\n        assert.strictEqual(instance.getActual(), 'not selected');\n        assert.strictEqual(\n          instance.message,\n          'Testing if element <.test_element> is not selected'\n        );\n        assert.ok(\n          message.startsWith(\n            'Testing if element <.test_element> is not selected'\n          ),\n          message\n        );\n      }\n    });\n  });\n\n  it('.not.selected assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      negate: true,\n      assertError: true,\n\n      assertion({reporter, instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), true);\n        assert.strictEqual(instance.getActual(), 'selected');\n        assert.strictEqual(\n          err.message,\n          `Testing if element <.test_element> is not selected in 5ms - expected \"is not selected\" but got: \"selected\" (${instance.elapsedTime}ms)`\n        );\n      }\n    });\n  });\n\n  it('selected assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'selected');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(\n          message.startsWith('Testing if element <.test_element> is selected'),\n          message\n        );\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('selected assertion passed with selector object and timeout', function () {\n    return assertionTest({\n      args: [{selector: '.test_element', timeout: 10, retryInterval: 15}],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'selected');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.retryAssertionTimeout, 10);\n        assert.strictEqual(instance.rescheduleInterval, 15);\n        assert.ok(\n          message.startsWith('Testing if element <.test_element> is selected'),\n          message\n        );\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('selected assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: 0,\n        value: false\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'not selected');\n        assert.strictEqual(\n          failure,\n          'Expected \"is selected\" but got: \"not selected\"'\n        );\n      }\n    });\n  });\n\n  it('selected assertion not - element not found', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(\n          instance.getActual(),\n          'element could not be located'\n        );\n        assert.strictEqual(instance.expected(), 'is selected');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(\n          failure,\n          'Expected \"is selected\" but got: \"element could not be located\"'\n        );\n        assert.strictEqual(\n          err.message,\n          `Testing if element <.test_element> is selected in 5ms - expected \"is selected\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`\n        );\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testTextEquals.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.textEquals', function () {\n  const assertionName = 'textEquals';\n  const api = 'getText';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('textEquals assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text result', 'Test message'],\n      commandResult: {\n        value: 'text result'\n      },\n      assertArgs: true,\n      assertMessage: true,\n      assertion({reporter, instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getValue(), 'text result');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('not.textEquals assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text result', 'Test message'],\n      commandResult: {\n        value: 'other text'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'other text');\n        assert.strictEqual(instance.getActual(), 'other text');\n        assert.strictEqual(instance.message, 'Test message');\n      }\n    });\n  });\n\n  it('not.textEquals assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text result', 'Test message'],\n      commandResult: {\n        value: 'text result'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'text result');\n        assert.strictEqual(instance.getActual(), 'text result');\n        assert.strictEqual(err.message, `Test message in 5ms - expected \"doesn't equal 'text result'\" but got: \"text result\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('textEquals assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'text result'],\n      commandResult: {\n        value: 'text result'\n      },\n      assertArgs: true,\n      assertResult: true,\n      assertion({instance, failure, message, err}) {\n        assert.ok(message.startsWith('Testing if element\\'s <.test_element> inner text equals \\'text result\\''), message);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'text result');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if element\\'s <.test_element> inner text equals \\'text result\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('textEquals assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text result', 'Test message'],\n      commandResult: {\n        value: 'not_expected'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'not_expected');\n        assert.strictEqual(failure, 'Expected \"equals \\'text result\\'\" but got: \"not_expected\"');\n      }\n    });\n  });\n\n  it('textEquals assertion - element not found', function () {\n    return assertionTest({\n      args: ['.test_element', 'text result', 'Test message'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'equals \\'text result\\'');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"equals \\'text result\\'\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Test message in 5ms - expected \"equals 'text result'\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/assertions/testTextMatches.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.textMatches', function () {\n  const assertionName = 'textMatches';\n  const api = 'getText';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('textMatches assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text', 'Test message'],\n      assertMessage: true,\n      assertArgs: true,\n      assertResult: true,\n      commandResult: {\n        value: 'expected text result'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'expected text result');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('textMatches assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text'],\n      commandResult: {\n        value: 'random value'\n      },\n      assertError: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'random value');\n        assert.strictEqual(instance.expected(), 'matches \\'text\\'');\n        assert.strictEqual(instance.getValue(), 'random value');\n        assert.strictEqual(failure, 'Expected \"matches \\'text\\'\" but got: \"random value\"');\n        assert.strictEqual(err.message, `Testing if the text matches <.test_element> 'text' in 5ms - expected \"matches 'text'\" but got: \"random value\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.textMatches assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text', 'Test message'],\n      commandResult: {\n        value: 'random value'\n      },\n      assertResult: true,\n      assertMessage: true,\n      assertArgs: true,\n      negate: true,\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'random value');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('textMatches assertion - element not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'text'],\n      commandResult: {\n        value: [],\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'matches \\'text\\'');\n        assert.strictEqual(failure, 'Expected \"matches \\'text\\'\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Testing if the text matches <.test_element> 'text' in 5ms - expected \"matches 'text'\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.textMatches assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'text'],\n      commandResult: {\n        value: 'expected text result'\n      },\n      assertResult: true,\n      negate: true,\n      assertError: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, 'Expected \"does not matches \\'text\\'\" but got: \"expected text result\"');\n        assert.strictEqual(instance.getActual(), 'expected text result');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testTitle.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.title', function () {\n  const assertionName = 'title';\n  const api = 'title';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('title assertion passed', function () {\n    return assertionTest({\n      args: ['Test Title', 'Test message'],\n      assertMessage: true,\n      assertResult: true,\n      commandResult: {\n        value: 'Test Title'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'Test Title');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.title assertion passed', function () {\n    return assertionTest({\n      args: ['Test Title'],\n      assertResult: true,\n      negate: true,\n      commandResult: {\n        value: 'Other Title'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'Other Title');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('title assertion failed', function () {\n    return assertionTest({\n      args: ['Test Title'],\n      assertError: true,\n      assertResult: true,\n      commandResult: {\n        value: 'Wrong Title'\n      },\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'Wrong Title');\n        assert.strictEqual(instance.expected(), 'is \\'Test Title\\'');\n        assert.strictEqual(instance.getValue(), 'Wrong Title');\n        assert.strictEqual(failure, 'Expected \"is \\'Test Title\\'\" but got: \"Wrong Title\"');\n        assert.strictEqual(err.message, `Testing if the page title equals 'Test Title' in 5ms - expected \"is 'Test Title'\" but got: \"Wrong Title\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.title assertion failed', function () {\n    return assertionTest({\n      args: ['Test Title'],\n      assertResult: true,\n      negate: true,\n      commandResult: {\n        value: 'Test Title'\n      },\n      assertError: true,\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, 'Expected \"is not \\'Test Title\\'\" but got: \"Test Title\"');\n        assert.strictEqual(instance.getActual(), 'Test Title');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/assertions/testTitleContains.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.titleContains', function () {\n  const assertionName = 'titleContains';\n  const api = 'title';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('titleContains assertion passed', function () {\n    return assertionTest({\n      args: ['Test Title', 'Test message'],\n      assertMessage: true,\n      assertResult: true,\n      commandResult: {\n        value: 'Test Title - '\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'Test Title - ');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('titleContains assertion failed without value field in response', function () {\n    return assertionTest({\n      args: ['Test Title'],\n      assertError: true,\n      commandResult: {\n        status: -1\n      },\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), '');\n        assert.strictEqual(instance.expected(), 'contains \\'Test Title\\'');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"contains \\'Test Title\\'\" but got: \"\"');\n        assert.strictEqual(err.message, `Testing if the page title contains 'Test Title' in 5ms - expected \"contains 'Test Title'\" but got: \"\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('titleContains assertion failed with empty response', function () {\n    return assertionTest({\n      args: ['Test Title'],\n      assertError: true,\n      commandResult: '',\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), '');\n        assert.strictEqual(instance.expected(), 'contains \\'Test Title\\'');\n        assert.strictEqual(instance.getValue(), '');\n        assert.strictEqual(failure, 'Expected \"contains \\'Test Title\\'\" but got: \"\"');\n        assert.strictEqual(err.message, `Testing if the page title contains 'Test Title' in 5ms - expected \"contains 'Test Title'\" but got: \"\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('titleContains assertion failed', function () {\n    return assertionTest({\n      args: ['Test Title'],\n      assertError: true,\n      commandResult: {\n        value: 'Wrong Title'\n      },\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'Wrong Title');\n        assert.strictEqual(instance.expected(), 'contains \\'Test Title\\'');\n        assert.strictEqual(instance.getValue(), 'Wrong Title');\n        assert.strictEqual(failure, 'Expected \"contains \\'Test Title\\'\" but got: \"Wrong Title\"');\n        assert.strictEqual(err.message, `Testing if the page title contains 'Test Title' in 5ms - expected \"contains 'Test Title'\" but got: \"Wrong Title\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.titleContains assertion passed', function () {\n    return assertionTest({\n      args: ['Test Title'],\n      assertResult: true,\n      negate: true,\n      commandResult: {\n        value: 'Other Title'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'Other Title');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.titleContains assertion failed', function () {\n    return assertionTest({\n      args: ['Test Title'],\n      assertResult: true,\n      negate: true,\n      commandResult: {\n        value: 'Test Title'\n      },\n      assertError: true,\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, 'Expected \"not contains \\'Test Title\\'\" but got: \"Test Title\"');\n        assert.strictEqual(instance.getActual(), 'Test Title');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testTitleEquals.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.titleEquals', function () {\n  const assertionName = 'titleEquals';\n  const api = 'title';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('titleEquals assertion passed', function () {\n    return assertionTest({\n      args: ['Nightwatch.js', 'Test message'],\n      assertMessage: true,\n      assertResult: true,\n      commandResult: {\n        value: 'Nightwatch.js'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'Nightwatch.js');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('titleEquals assertion failed', function () {\n    return assertionTest({\n      args: ['Nightwatch.js'],\n      commandResult: {\n        value: 'John Doe'\n      },\n      assertError: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'John Doe');\n        assert.strictEqual(instance.expected(), 'is \\'Nightwatch.js\\'');\n        assert.strictEqual(instance.getValue(), 'John Doe');\n        assert.strictEqual(failure, 'Expected \"is \\'Nightwatch.js\\'\" but got: \"John Doe\"');\n        assert.strictEqual(err.message, `Testing if the page title equals 'Nightwatch.js' in 5ms - expected \"is 'Nightwatch.js'\" but got: \"John Doe\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.titleEquals assertion passed', function () {\n    return assertionTest({\n      args: ['Nightwatch.js'],\n      commandResult: {\n        value: 'John Doe'\n      },\n      assertResult: true,\n      negate: true,\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'John Doe');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.titleEquals assertion failed', function () {\n    return assertionTest({\n      args: ['Nightwatch.js'],\n      commandResult: {\n        value: 'Nightwatch.js'\n      },\n      assertResult: true,\n      negate: true,\n      assertError: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, 'Expected \"is not \\'Nightwatch.js\\'\" but got: \"Nightwatch.js\"');\n        assert.strictEqual(instance.getActual(), 'Nightwatch.js');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testTitleMatches.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.titleMatches', function () {\n  const assertionName = 'titleMatches';\n  const api = 'title';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('titleMatches assertion passed', function () {\n    return assertionTest({\n      args: ['^Night', 'Test message'],\n      assertMessage: true,\n      assertResult: true,\n      commandResult: {\n        value: 'Nightwatch.js'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'Nightwatch.js');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('titleMatches assertion failed', function () {\n    return assertionTest({\n      args: ['^Night'],\n      commandResult: {\n        value: 'John Doe'\n      },\n      assertError: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'John Doe');\n        assert.strictEqual(instance.expected(), 'matches \\'^Night\\'');\n        assert.strictEqual(instance.getValue(), 'John Doe');\n        assert.strictEqual(failure, 'Expected \"matches \\'^Night\\'\" but got: \"John Doe\"');\n        assert.strictEqual(err.message, `Testing if the page title matches '^Night' in 5ms - expected \"matches '^Night'\" but got: \"John Doe\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.titleMatches assertion passed', function () {\n    return assertionTest({\n      args: ['^Night'],\n      commandResult: {\n        value: 'John Doe'\n      },\n      assertResult: true,\n      negate: true,\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'John Doe');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.titleMatches assertion failed', function () {\n    return assertionTest({\n      args: ['^Night'],\n      commandResult: {\n        value: 'Nightwatch.js'\n      },\n      assertResult: true,\n      negate: true,\n      assertError: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, 'Expected \"does not matches \\'^Night\\'\" but got: \"Nightwatch.js\"');\n        assert.strictEqual(instance.getActual(), 'Nightwatch.js');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testUrlContains.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.urlContains', function () {\n  const assertionName = 'urlContains';\n  const api = 'url';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('urlContains assertion passed', function () {\n    return assertionTest({\n      args: ['nightwatchjs', 'Test message'],\n      commandResult: {\n        value: 'https://nightwatchjs.org'\n      },\n      assertMessage: true,\n      assertResult: true,\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({reporter, instance, failure, err}) {\n        assert.strictEqual(err, undefined);\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'https://nightwatchjs.org');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('urlContains assertion failed without value field in response', function () {\n    return assertionTest({\n      args: ['nightwatchjs'],\n      assertError: true,\n      commandResult: {\n        status: -1\n      },\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), '');\n        assert.strictEqual(instance.expected(), 'contains \\'nightwatchjs\\'');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"contains \\'nightwatchjs\\'\" but got: \"\"');\n        assert.strictEqual(err.message, `Testing if the URL contains 'nightwatchjs' in 5ms - expected \"contains 'nightwatchjs'\" but got: \"\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('urlContains assertion failed with empty response', function () {\n    return assertionTest({\n      args: ['nightwatchjs'],\n      assertError: true,\n      commandResult: '',\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), '');\n        assert.strictEqual(instance.expected(), 'contains \\'nightwatchjs\\'');\n        assert.strictEqual(instance.getValue(), '');\n        assert.strictEqual(failure, 'Expected \"contains \\'nightwatchjs\\'\" but got: \"\"');\n        assert.strictEqual(err.message, `Testing if the URL contains 'nightwatchjs' in 5ms - expected \"contains 'nightwatchjs'\" but got: \"\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('urlContains assertion failed', function () {\n    return assertionTest({\n      args: ['http://'],\n      commandResult: {\n        value: 'https://nightwatchjs.org'\n      },\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'https://nightwatchjs.org');\n        assert.strictEqual(instance.expected(), 'contains \\'http://\\'');\n        assert.strictEqual(instance.getValue(), 'https://nightwatchjs.org');\n        assert.strictEqual(failure, 'Expected \"contains \\'http://\\'\" but got: \"https://nightwatchjs.org\"');\n        assert.strictEqual(err.message, `Testing if the URL contains 'http://' in 5ms - expected \"contains 'http://'\" but got: \"https://nightwatchjs.org\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.urlContains assertion passed', function () {\n    return assertionTest({\n      args: ['http://'],\n      assertResult: true,\n      negate: true,\n      commandResult: {\n        value: 'https://nightwatchjs.org'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'https://nightwatchjs.org');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.urlContains assertion failed', function () {\n    return assertionTest({\n      args: ['https://nightwatchjs.org'],\n      assertResult: true,\n      negate: true,\n      commandResult: {\n        value: 'https://nightwatchjs.org'\n      },\n      assertError: true,\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, 'Expected \"not contains \\'https://nightwatchjs.org\\'\" but got: \"https://nightwatchjs.org\"');\n        assert.strictEqual(instance.getActual(), 'https://nightwatchjs.org');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testUrlEquals.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.urlEquals', function () {\n  const assertionName = 'urlEquals';\n  const api = 'url';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('urlEquals assertion passed', function () {\n    return assertionTest({\n      args: ['https://nightwatchjs.org', 'Test message'],\n      assertMessage: true,\n      assertResult: true,\n      commandResult: {\n        value: 'https://nightwatchjs.org'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'https://nightwatchjs.org');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('urlEquals assertion failed', function () {\n    return assertionTest({\n      args: ['https://ecosia.org'],\n      commandResult: {\n        value: 'https://nightwatchjs.org'\n      },\n      assertError: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'https://nightwatchjs.org');\n        assert.strictEqual(instance.expected(), 'is \\'https://ecosia.org\\'');\n        assert.strictEqual(instance.getValue(), 'https://nightwatchjs.org');\n        assert.strictEqual(failure, 'Expected \"is \\'https://ecosia.org\\'\" but got: \"https://nightwatchjs.org\"');\n        assert.strictEqual(err.message, `Testing if the URL is 'https://ecosia.org' in 5ms - expected \"is 'https://ecosia.org'\" but got: \"https://nightwatchjs.org\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.urlEquals assertion passed', function () {\n    return assertionTest({\n      args: ['https://nightwatchjs.org'],\n      commandResult: {\n        value: 'https://ecosia.org'\n      },\n      assertResult: true,\n      negate: true,\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'https://ecosia.org');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.urlEquals assertion failed', function () {\n    return assertionTest({\n      args: ['https://nightwatchjs.org'],\n      commandResult: {\n        value: 'https://nightwatchjs.org'\n      },\n      assertResult: true,\n      negate: true,\n      assertError: true,\n      assertion({reporter, instance, failure}) {\n        assert.strictEqual(failure, 'Expected \"is not \\'https://nightwatchjs.org\\'\" but got: \"https://nightwatchjs.org\"');\n        assert.strictEqual(instance.getActual(), 'https://nightwatchjs.org');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testUrlMatches.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.urlMatches', function () {\n  const assertionName = 'urlMatches';\n  const api = 'url';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('urlMatches assertion passed', function () {\n    return assertionTest({\n      args: ['nightwatch', 'Test message'],\n      assertMessage: true,\n      assertResult: true,\n      commandResult: {\n        value: 'https://nightwatchjs.org/'\n      },\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'https://nightwatchjs.org/');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('urlMatches assertion failed', function () {\n    return assertionTest({\n      args: ['nightwatch'],\n      commandResult: {\n        value: 'John Doe'\n      },\n      assertError: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'John Doe');\n        assert.strictEqual(instance.expected(), 'matches \\'nightwatch\\'');\n        assert.strictEqual(instance.getValue(), 'John Doe');\n        assert.strictEqual(failure, 'Expected \"matches \\'nightwatch\\'\" but got: \"John Doe\"');\n        assert.strictEqual(err.message, `Testing if the URL matches 'nightwatch' in 5ms - expected \"matches 'nightwatch'\" but got: \"John Doe\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('.not.urlMatches assertion passed', function () {\n    return assertionTest({\n      args: ['nightwatch'],\n      commandResult: {\n        value: 'John Doe'\n      },\n      assertResult: true,\n      negate: true,\n      assertApiCommandArgs(args) {\n        assert.strictEqual(args.length, 1);\n        assert.strictEqual(typeof args[0], 'function');\n      },\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.getActual(), 'John Doe');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.urlMatches assertion failed', function () {\n    return assertionTest({\n      args: ['nightwatch'],\n      commandResult: {\n        value: 'https://nightwatchjs.org/'\n      },\n      assertResult: true,\n      negate: true,\n      assertError: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(failure, 'Expected \"does not matches \\'nightwatch\\'\" but got: \"https://nightwatchjs.org/\"');\n        assert.strictEqual(instance.getActual(), 'https://nightwatchjs.org/');\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testValue.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.value', function () {\n  const assertionName = 'value';\n  const api = 'getValue';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('value assertion passed', function() {\n    return assertionTest({\n      args: ['.test_element', 'some-value', 'Test message'],\n      commandResult: {\n        status: 0,\n        value: 'some-value'\n      },\n      assertMessage: true,\n      assertArgs: true,\n      assertion({reporter, instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('not.value assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        value: 'second'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'second');\n        assert.strictEqual(instance.getActual(), 'second');\n        assert.strictEqual(instance.message, 'Testing if value of element <.test_element> doesn\\'t equal \\'some-value\\'');\n        assert.ok(message.startsWith('Testing if value of element <.test_element> doesn\\'t equal \\'some-value\\''), message);\n      }\n    });\n  });\n\n  it('not.value assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        value: 'some-value'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'some-value');\n        assert.strictEqual(instance.getActual(), 'some-value');\n        assert.strictEqual(err.message, `Testing if value of element <.test_element> doesn't equal 'some-value' in 5ms - expected \"not equals 'some-value'\" but got: \"some-value\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('value assertion passed with selector object', function() {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'some-value'],\n      commandResult: {\n        status: 0,\n        value: 'some-value'\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, err, message}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'some-value');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if value of element <.test_element> equals \\'some-value\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('value assertion failed', function() {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        status: 0,\n        value: 'wrong-value'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'wrong-value');\n        assert.strictEqual(failure, 'Expected \"equals \\'some-value\\'\" but got: \"wrong-value\"');\n      }\n    });\n  });\n\n  it('value assertion - element not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'some-value', 'Test value of element %s == %s'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'equals \\'some-value\\'');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"equals \\'some-value\\'\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Test value of element <.test_element> == 'some-value' in 5ms - expected \"equals 'some-value'\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('attributeEquals assertion - value attribute not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        status: 0,\n        value: null\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, message, failure}) {\n        assert.strictEqual(message, `Testing if value of element <.test_element> equals 'some-value' in 5ms - expected \"equals 'some-value'\" but got: \"Element does not have a value attribute\" (${instance.elapsedTime}ms)`);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(instance.getActual(), 'Element does not have a value attribute');\n      }\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/assertions/testValueContains.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.valueContains', function () {\n  const assertionName = 'valueContains';\n  const api = 'getValue';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('valueContains assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'some-value', 'Test message'],\n      commandResult: {\n        status: 0,\n        value: 'contains-some-value'\n      },\n      assertMessage: true,\n      assertArgs: true,\n      assertion({reporter, instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('not.valueContains assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        status: 0,\n        value: 'contains-other-value'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'contains-other-value');\n        assert.strictEqual(instance.getActual(), 'contains-other-value');\n        assert.strictEqual(instance.message, 'Testing if value of element <.test_element> doesn\\'t contain \\'some-value\\'');\n        assert.ok(message.startsWith('Testing if value of element <.test_element> doesn\\'t contain \\'some-value\\''), message);\n      }\n    });\n  });\n\n  it('not.valueContains assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        value: 'some-value'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'some-value');\n        assert.strictEqual(instance.getActual(), 'some-value');\n        assert.strictEqual(err.message, `Testing if value of element <.test_element> doesn't contain 'some-value' in 5ms - expected \"not contains 'some-value'\" but got: \"some-value\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('valueContains assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'some-value'],\n      commandResult: {\n        status: 0,\n        value: 'contains-some-value'\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'contains-some-value');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if value of element <.test_element> contains \\'some-value\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('valueContains assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        status: 0,\n        value: 'wrong-value'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'wrong-value');\n        assert.strictEqual(failure, 'Expected \"contains \\'some-value\\'\" but got: \"wrong-value\"');\n      }\n    });\n  });\n\n  it('valueContains assertion - element not found', function () {\n    return assertionTest({\n      args: ['.test_element', 'some-value', 'Test value of element \"%s\" contains %s'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'contains \\'some-value\\'');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"contains \\'some-value\\'\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Test value of element \"<.test_element>\" contains 'some-value' in 5ms - expected \"contains 'some-value'\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('valueContains assertion stale element reference', function () {\n    let calls = 0;\n    const commandResult = function() {\n      if (calls === 0) {\n        calls++;\n\n        return {\n          state: 'stale element reference',\n          status: -1,\n          errorStatus: 10\n        };\n      }\n\n      return {\n        status: 0,\n        value: 'contains-some-value'\n      };\n    };\n\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult,\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.strictEqual(instance.getActual(), 'contains-some-value');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if value of element <.test_element> contains \\'some-value\\''));\n      }\n    });\n  });\n\n  it('valueContains assertion - value attribute not found', function () {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        status: 0,\n        value: null\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, message, failure}) {\n        assert.strictEqual(message, `Testing if value of element <.test_element> contains 'some-value' in 5ms - expected \"contains 'some-value'\" but got: \"Element does not have a value attribute\" (${instance.elapsedTime}ms)`);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(instance.getActual(), 'Element does not have a value attribute');\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testValueEquals.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.valueEquals', function () {\n  const assertionName = 'valueEquals';\n  const api = 'getValue';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('value assertion passed', function() {\n    return assertionTest({\n      args: ['.test_element', 'some-value', 'Test message'],\n      commandResult: {\n        status: 0,\n        value: 'some-value'\n      },\n      assertMessage: true,\n      assertArgs: true,\n      assertion({reporter, instance, failure}) {\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('not.valueEquals assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        value: 'second'\n      },\n      negate: true,\n      assertion({reporter, instance, queueOpts, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'second');\n        assert.strictEqual(instance.getActual(), 'second');\n        assert.strictEqual(instance.message, 'Testing if value of element <.test_element> doesn\\'t equal \\'some-value\\'');\n        assert.ok(message.startsWith('Testing if value of element <.test_element> doesn\\'t equal \\'some-value\\''), message);\n      }\n    });\n  });\n\n  it('not.valueEquals assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        value: 'some-value'\n      },\n      negate: true,\n      assertError: true,\n      assertion({instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), 'some-value');\n        assert.strictEqual(instance.getActual(), 'some-value');\n        assert.strictEqual(err.message, `Testing if value of element <.test_element> doesn't equal 'some-value' in 5ms - expected \"not equals 'some-value'\" but got: \"some-value\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('value assertion passed with selector object', function() {\n    return assertionTest({\n      args: [{selector: '.test_element'}, 'some-value'],\n      commandResult: {\n        status: 0,\n        value: 'some-value'\n      },\n      assertArgs: true,\n      assertion({reporter, instance, failure, err, message}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'some-value');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if value of element <.test_element> equals \\'some-value\\''), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('value assertion failed', function() {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        status: 0,\n        value: 'wrong-value'\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'wrong-value');\n        assert.strictEqual(failure, 'Expected \"equals \\'some-value\\'\" but got: \"wrong-value\"');\n      }\n    });\n  });\n\n  it('value assertion - element not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'some-value', 'Test value of element %s == %s'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'equals \\'some-value\\'');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"equals \\'some-value\\'\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Test value of element <.test_element> == 'some-value' in 5ms - expected \"equals 'some-value'\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('attributeEquals assertion - value attribute not found', function() {\n    return assertionTest({\n      args: ['.test_element', 'some-value'],\n      commandResult: {\n        status: 0,\n        value: null\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, message, failure}) {\n        assert.strictEqual(message, `Testing if value of element <.test_element> equals 'some-value' in 5ms - expected \"equals 'some-value'\" but got: \"\" (${instance.elapsedTime}ms)`);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), '');\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/assertions/testVisible.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('assert.visible', function () {\n  const assertionName = 'visible';\n  const api = 'isVisible';\n\n  function assertionTest(opts) {\n    return Globals.assertion(assertionName, api, opts);\n  }\n\n  it('visible assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element', 'Test message'],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      assertArgs: true,\n      assertMessage: true,\n      assertion({reporter, instance, failure, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(failure, false);\n        assert.strictEqual(instance.hasFailure(), false);\n      }\n    });\n  });\n\n  it('.not.visible assertion passed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: 0,\n        value: false\n      },\n      negate: true,\n\n      assertion({reporter, instance, queueOpts, err, message}) {\n        assert.strictEqual(typeof err, 'undefined');\n        assert.strictEqual(queueOpts.negate, true);\n\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), false);\n        assert.strictEqual(instance.getActual(), 'not visible');\n        assert.strictEqual(instance.message, 'Testing if element <.test_element> is not visible');\n        assert.ok(message.startsWith('Testing if element <.test_element> is not visible'), message);\n      }\n    });\n  });\n\n  it('.not.visible assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      negate: true,\n      assertError: true,\n\n      assertion({reporter, instance, queueOpts, err}) {\n        assert.strictEqual(queueOpts.negate, true);\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.getValue(), true);\n        assert.strictEqual(instance.getActual(), 'visible');\n        assert.strictEqual(err.message, `Testing if element <.test_element> is not visible in 5ms - expected \"is not visible\" but got: \"visible\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('visible assertion passed with selector object', function () {\n    return assertionTest({\n      args: [{selector: '.test_element'}],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'visible');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.ok(message.startsWith('Testing if element <.test_element> is visible'), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n\n  it('visible assertion passed with selector object and timeout', function () {\n    return assertionTest({\n      args: [{selector: '.test_element', timeout: 10, retryInterval: 15}],\n      commandResult: {\n        status: 0,\n        value: true\n      },\n      assertion({instance, failure, message, err}) {\n        assert.strictEqual(err, undefined);\n        assert.deepStrictEqual(instance.options, {elementSelector: true});\n        assert.strictEqual(instance.getActual(), 'visible');\n        assert.strictEqual(instance.hasFailure(), false);\n        assert.strictEqual(instance.retryAssertionTimeout, 10);\n        assert.strictEqual(instance.rescheduleInterval, 15);\n        assert.ok(message.startsWith('Testing if element <.test_element> is visible'), message);\n        assert.strictEqual(failure, false);\n      }\n    });\n  });\n  \n  it('visible assertion failed', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: 0,\n        value: false\n      },\n      assertError: true,\n      assertResult: true,\n      assertion({instance, failure}) {\n        assert.strictEqual(instance.getActual(), 'not visible');\n        assert.strictEqual(failure, 'Expected \"is visible\" but got: \"not visible\"');\n      }\n    });\n  });\n\n  it('visible assertion not - element not found', function () {\n    return assertionTest({\n      args: ['.test_element'],\n      commandResult: {\n        status: -1\n      },\n      assertError: true,\n      assertFailure: true,\n      assertResult: true,\n      assertion({instance, failure, err}) {\n        assert.strictEqual(instance.getActual(), 'element could not be located');\n        assert.strictEqual(instance.expected(), 'is visible');\n        assert.strictEqual(instance.getValue(), null);\n        assert.strictEqual(failure, 'Expected \"is visible\" but got: \"element could not be located\"');\n        assert.strictEqual(err.message, `Testing if element <.test_element> is visible in 5ms - expected \"is visible\" but got: \"element could not be located\" (${instance.elapsedTime}ms)`);\n      }\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/commands/client/testAxeCommands.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('accessibility commands', function () {\n\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test axe commands loaded onto the main api', function () {\n    assert.strictEqual(typeof this.client.api.axeInject, 'function');\n    assert.strictEqual(typeof this.client.api.axeRun, 'function');\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testCaptureNetworkRequests.js",
    "content": "const assert = require('assert');\nconst common = require('../../../../common.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst cdp = common.require('transport/selenium-webdriver/cdp.js');\n\ndescribe('.captureNetworkRequests()', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.captureNetworkRequests()', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {};\n\n      const cdpNetworkEvent = JSON.stringify({\n        method: 'Network.requestWillBeSent',\n        params: {\n          request: {\n            url: 'https://www.google.com',\n            method: 'GET',\n            headers: []\n          }\n        }\n      });\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: (event, callback) => {\n              expected['wsEvent'] = event;\n              callback(cdpNetworkEvent);\n            }\n          },\n          execute: function(command, params) {\n            expected['cdpCommand'] = command;\n            expected['cdpParams'] = params;\n          }\n        });\n      };\n\n      const userCallback = (requestParams) => {\n        expected['requestParams'] = requestParams;\n      };\n      client.api.captureNetworkRequests(userCallback, function () {\n        assert.deepEqual(expected.cdpCommand, 'Network.enable');\n        assert.deepEqual(expected.cdpParams, {});\n        assert.strictEqual(expected.wsEvent, 'message');\n        assert.deepEqual(expected.requestParams, JSON.parse(cdpNetworkEvent).params);\n      });\n      client.start(done);\n    });\n  });\n\n  it('browser.network.captureRequests()', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {};\n\n      const cdpNetworkEvent = JSON.stringify({\n        method: 'Network.requestWillBeSent',\n        params: {\n          request: {\n            url: 'https://www.google.com',\n            method: 'GET',\n            headers: []\n          }\n        }\n      });\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: (event, callback) => {\n              expected['wsEvent'] = event;\n              callback(cdpNetworkEvent);\n            }\n          },\n          execute: function(command, params) {\n            expected['cdpCommand'] = command;\n            expected['cdpParams'] = params;\n          }\n        });\n      };\n\n      const userCallback = (requestParams) => {\n        expected['requestParams'] = requestParams;\n      };\n      client.api.network.captureRequests(userCallback, function () {\n        assert.deepEqual(expected.cdpCommand, 'Network.enable');\n        assert.deepEqual(expected.cdpParams, {});\n        assert.strictEqual(expected.wsEvent, 'message');\n        assert.deepEqual(expected.requestParams, JSON.parse(cdpNetworkEvent).params);\n      });\n      client.start(done);\n    });\n  });\n\n  it('throws error without callback', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      client.api.captureNetworkRequests(undefined, function (result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'Callback is missing from .captureNetworkRequests() command.');\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('browser.captureNetworkRequests - driver not supported', function(done) {\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      // eslint-disable-next-line\n      const userCallback = (requestParams) => {console.log(requestParams)}\n      client.api.captureNetworkRequests(userCallback, function(result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .captureNetworkRequests() is only supported in Chrome and Edge drivers');\n      });\n      client.start(done);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testEnablePerformanceMetrics.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\n\ndescribe('.enablePerformanceMetrics()', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.enablePerformanceMetrics()', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expectedCdpCommands = [];\n\n      client.transport.driver.sendAndGetDevToolsCommand = (command) =>{\n        expectedCdpCommands.push(command);\n      };\n      client.api.enablePerformanceMetrics(undefined, function (){\n        assert.deepEqual(expectedCdpCommands, ['Performance.disable', 'Performance.enable']);\n      });\n      client.start(done);\n    });\n  });\n\n  it('browser.enablePerformanceMetrics(false)', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expectedCdpCommands = [];\n\n      client.transport.driver.sendAndGetDevToolsCommand = (command) =>{\n        expectedCdpCommands.push(command);\n      };\n      client.api.enablePerformanceMetrics(false, function (){\n        assert.deepEqual(expectedCdpCommands, ['Performance.disable']);\n      });\n      client.start(done);\n    });\n  });\n\n  it('browser.enablePerformanceMetrics - driver not supported', function(done){\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      client.api.enablePerformanceMetrics(true, function(result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .enablePerformanceMetrics() is only supported in Chrome and Edge drivers');\n      });\n      client.start(done);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testEnd.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('.end()', function() {\n  describe('with backwards compat mode', function() {\n    beforeEach(function(done) {\n      CommandGlobals.beforeEach.call(this, done, {\n        backwards_compatibility_mode: true\n      });\n    });\n\n    afterEach(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('browser.end();', function (done) {\n      this.client.api.end(result => {\n        assert.strictEqual(result.status, 0);\n        assert.strictEqual(this.client.api.sessionId, null);\n      });\n\n      this.client.start(done);\n    });\n\n    it('browser.end(true) - forceEnd by default true', function (done) { \n      this.client.api.end(true, result => {\n        assert.strictEqual(result.status, 0);\n        assert.strictEqual(this.client.sessionId, null);\n      });\n      this.client.start(done);\n    });\n\n    it('browser.end(false) - do not end sesion', function(done) {\n      this.client.api.end(false, result=> {\n        assert.strictEqual(result, null);\n        assert.strictEqual(this.client.sessionId, '1352110219202');\n      });\n      this.client.start(done);\n    });\n\n    it('browser.end() - no session id', function (done) {\n      this.client.api.end();\n      this.client.api.end(function callback(result) {\n        assert.strictEqual(result, null);\n      });\n\n      this.client.start(done);\n    });\n\n    it('browser.end() - with screenshot', function (done) {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/screenshot',\n        method: 'GET',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: '==content'\n        })\n      }, true);\n\n      Nightwatch.initClient({\n        screenshots: {\n          enabled: true,\n          on_failure: true,\n          path: 'screens'\n        }\n      }).then(client => {\n        assert.strictEqual(typeof client.settings.screenshots.filename_format, 'function');\n\n        const fileNameFailed = client.settings.screenshots.filename_format({\n          testSuite: 'xxTestSuite',\n          testCase: 'xxTestCase',\n          isError: false\n        });\n\n        const fileNameError = client.settings.screenshots.filename_format({\n          testSuite: 'xxTestSuite',\n          testCase: 'xxTestCase',\n          isError: true\n        });\n\n        assert.ok(fileNameFailed.startsWith(`xxTestSuite${path.sep}xxTestCase_FAILED_`));\n        assert.ok(fileNameFailed.endsWith('.png'));\n        assert.ok(fileNameError.startsWith(`xxTestSuite${path.sep}xxTestCase_ERROR_`));\n        assert.ok(fileNameError.endsWith('.png'));\n\n        client.api.currentTest = {\n          module: 'test_module',\n          name: 'test_name',\n          results: {\n            failed: 1,\n            passed: 0\n          }\n        };\n\n        client.api.end(function callback(result) {\n          assert.strictEqual(result.status, 0);\n        });\n\n        client.start(done);\n      }).catch(err => done(err));\n    });\n\n\n    it('browser.end() - reuse browser session', function (done) {\n\n      Nightwatch.initClient({globals: {reuseBrowserSession: true}})\n        .then(client => {\n          client.api.end(function callback(result) {\n            assert.strictEqual(result, null);\n            assert.strictEqual(client.sessionId, '1352110219202');\n          });\n\n          client.start(done);\n        }).catch(err => done(err));\n    });\n\n\n    it('browser.end() - failures and screenshots disabled', function (done) {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/screenshot',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: '==content'\n        })\n      }, true);\n\n      Nightwatch.initClient({\n        backwards_compatibility_mode: true,\n        screenshots: {\n          enabled: true,\n          on_failure: false,\n          path: './screens'\n        }\n      }).then(client => {\n        client.api.currentTest = {\n          module: 'test_module',\n          name: 'test_name',\n          results: {\n            failed: 1,\n            passed: 0\n          }\n        };\n\n        const saveScreenshot = client.api.saveScreenshot;\n        client.api.saveScreenshot = function (file, callback) {\n          throw new Error('saveScreenshot should not be called');\n        };\n\n        client.api.end(function callback(result) {\n          assert.strictEqual(result.status, 0);\n        });\n\n        client.start(function(err) {\n          client.api.saveScreenshot = saveScreenshot;\n          done(err);\n        });\n      });\n    });\n  });\n\n  describe('without compat mode', function() {\n    beforeEach(function(done) {\n      CommandGlobals.beforeEach.call(this, done);\n    });\n\n    afterEach(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('browser.end();', function (done) {\n      this.client.api.end(result => {\n        assert.strictEqual(result.status, 0);\n        assert.strictEqual(this.client.api.sessionId, null);\n      });\n\n      this.client.start(done);\n    });\n\n    it('browser.end() - no session id', function (done) {\n      this.client.api.end();\n      this.client.api.end(function callback(result) {\n        assert.strictEqual(result, null);\n      });\n\n      this.client.start(done);\n    });\n\n    it('browser.end() - with screenshot', function (done) {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/screenshot',\n        method: 'GET',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: '==content'\n        })\n      }, true);\n\n      Nightwatch.initClient({\n        screenshots: {\n          enabled: true,\n          on_failure: true,\n          path: 'screens'\n        }\n      }).then(client => {\n        assert.strictEqual(typeof client.settings.screenshots.filename_format, 'function');\n\n        const fileNameFailed = client.settings.screenshots.filename_format({\n          testSuite: 'xxTestSuite',\n          testCase: 'xxTestCase',\n          isError: false\n        });\n\n        const fileNameError = client.settings.screenshots.filename_format({\n          testSuite: 'xxTestSuite',\n          testCase: 'xxTestCase',\n          isError: true\n        });\n\n        assert.ok(fileNameFailed.startsWith(`xxTestSuite${path.sep}xxTestCase_FAILED_`));\n        assert.ok(fileNameFailed.endsWith('.png'));\n        assert.ok(fileNameError.startsWith(`xxTestSuite${path.sep}xxTestCase_ERROR_`));\n        assert.ok(fileNameError.endsWith('.png'));\n\n        client.api.currentTest = {\n          module: 'test_module',\n          name: 'test_name',\n          results: {\n            failed: 1,\n            passed: 0\n          }\n        };\n\n        client.api.end(function callback(result) {\n          assert.strictEqual(result.status, 0);\n        });\n\n        client.start(done);\n      }).catch(err => done(err));\n    });\n\n    it('browser.end() - failures and screenshots disabled', function (done) {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/screenshot',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: '==content'\n        })\n      }, true);\n\n      Nightwatch.initClient({\n        screenshots: {\n          enabled: true,\n          on_failure: false,\n          path: './screens'\n        }\n      }).then(client => {\n        client.api.currentTest = {\n          module: 'test_module',\n          name: 'test_name',\n          results: {\n            failed: 1,\n            passed: 0\n          }\n        };\n\n        const saveScreenshot = client.api.saveScreenshot;\n        client.api.saveScreenshot = function (file, callback) {\n          throw new Error('saveScreenshot should not be called');\n        };\n\n        client.api.end(function callback(result) {\n          assert.strictEqual(result.status, 0);\n        });\n\n        client.start(function(err) {\n          client.api.saveScreenshot = saveScreenshot;\n          done(err);\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testGetPerformanceMetrics.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\n\ndescribe('.getPerformanceMetrics()', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.getPerformanceMetrics()', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expectedCdpCommands = [];\n\n      const cdpReturnedMetrics = {\n        metrics: [\n          {name: 'Documents', value: 1},\n          {name: 'Frames', value: 5},\n          {name: 'LayoutCount', value: 82}\n        ]\n      };\n      const finalReturnedMetrics = {\n        'Documents': 1,\n        'Frames': 5,\n        'LayoutCount': 82\n      };\n\n      client.transport.driver.sendAndGetDevToolsCommand = (command) =>{\n        expectedCdpCommands.push(command);\n\n        return Promise.resolve(cdpReturnedMetrics);\n      };\n      client.api.getPerformanceMetrics(function (metrics) {\n        assert.deepEqual(metrics.value, finalReturnedMetrics);\n        assert.deepEqual(expectedCdpCommands, ['Performance.getMetrics']);\n      });\n      client.start(done);\n    });\n  });\n\n  it('browser.getPerformanceMetrics - driver not supported', function(done){\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      client.api.getPerformanceMetrics(function(result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .getPerformanceMetrics() is only supported in Chrome and Edge drivers');\n      });\n      client.start(done);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testInit.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('.init()', function() {\n  describe('with backwards compat mode', function() {\n    before(function(done) {\n      CommandGlobals.beforeEach.call(this, done, {\n        backwards_compatibility_mode: true\n      });\n    });\n\n    after(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('browser.init();', function (done) {\n      this.client.api.launchUrl = 'http://localhost';\n      this.client.api.init(result => {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n\n\n    it('browser.init() - with url', function (done) {\n      this.client.api.init('http://localhost/test_url', result => {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n  });\n\n  describe('without compat mode', function() {\n    before(function(done) {\n      CommandGlobals.beforeEach.call(this, done);\n    });\n\n    after(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('browser.init();', function (done) {\n      this.client.api.launchUrl = 'http://localhost';\n      this.client.api.init(result => {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n\n\n    it('browser.init() - with url', function (done) {\n      this.client.api.init('http://localhost/test_url', result => {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testLocateStrategy.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('Locate strategies', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.useXpath()', function(done) {\n    let client = this.client;\n    this.client.api.useXpath(function() {\n      assert.strictEqual(client.locateStrategy, 'xpath');\n    });\n\n    this.client.start(done);\n  });\n\n  it('browser.useCss()', function(done) {\n    let client = this.client;\n    this.client.api.useCss(function() {\n      assert.strictEqual(client.locateStrategy, 'css selector');\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testMockNetworkResponse.js",
    "content": "const assert = require('assert');\nconst common = require('../../../../common.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst cdp = common.require('transport/selenium-webdriver/cdp.js');\n\ndescribe('.mockNetworkResponse()', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.mockNetworkResponse(urlToIntercept, {status, headers, body}) with url match', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {\n        cdpCommands: []\n      };\n\n      // Parameters of actual request made by browser\n      const cdpFetchRequestPauseEvent = JSON.stringify({\n        method: 'Fetch.requestPaused',\n        params: {\n          requestId: '123',\n          request: {\n            url: 'https://www.google.com/'\n          }\n        }\n      });\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: (event, callback) => {\n              expected['wsEvent'] = event;\n              callback(cdpFetchRequestPauseEvent);\n            }\n          },\n          execute: function(command, params) {\n            expected.cdpCommands.push(command);\n            if (command === 'Fetch.fulfillRequest') {\n              expected['requestId'] = params.requestId;\n              expected['responseCode'] = params.responseCode;\n              expected['responseHeaders'] = params.responseHeaders;\n              expected['responseBody'] = params.body;\n            }\n          }\n        });\n      };\n\n      const response = {\n        status: 200,\n        headers: {'Content-Type': 'UTF-8'},\n        body: 'Hey there!'\n      };\n      client.api.mockNetworkResponse('https://www.google.com/', response, function () {\n        // Assert final response with response passed\n        assert.strictEqual(expected.responseCode, response.status);\n        assert.deepEqual(expected.responseHeaders, [{name: 'Content-Type', value: 'UTF-8'}]);\n        assert.strictEqual(expected.responseBody, Buffer.from(response.body, 'utf-8').toString('base64'));\n\n        assert.strictEqual(expected.requestId, JSON.parse(cdpFetchRequestPauseEvent).params.requestId);\n        assert.strictEqual(expected.wsEvent, 'message');\n        assert.deepEqual(expected.cdpCommands, ['Fetch.fulfillRequest', 'Fetch.enable', 'Network.setCacheDisabled']);\n      });\n  \n      client.start(done);\n    });\n  });\n\n  it('browser.network.mockResponse(urlToIntercept, {status, headers, body}) with url match', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {\n        cdpCommands: []\n      };\n\n      // Parameters of actual request made by browser\n      const cdpFetchRequestPauseEvent = JSON.stringify({\n        method: 'Fetch.requestPaused',\n        params: {\n          requestId: '123',\n          request: {\n            url: 'https://www.google.com/'\n          }\n        }\n      });\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: (event, callback) => {\n              expected['wsEvent'] = event;\n              callback(cdpFetchRequestPauseEvent);\n            }\n          },\n          execute: function(command, params) {\n            expected.cdpCommands.push(command);\n            if (command === 'Fetch.fulfillRequest') {\n              expected['requestId'] = params.requestId;\n              expected['responseCode'] = params.responseCode;\n              expected['responseHeaders'] = params.responseHeaders;\n              expected['responseBody'] = params.body;\n            }\n          }\n        });\n      };\n\n      const response = {\n        status: 200,\n        headers: {'Content-Type': 'UTF-8'},\n        body: 'Hey there!'\n      };\n      client.api.network.mockResponse('https://www.google.com/', response, function () {\n        // Assert final response with response passed\n        assert.strictEqual(expected.responseCode, response.status);\n        assert.deepEqual(expected.responseHeaders, [{name: 'Content-Type', value: 'UTF-8'}]);\n        assert.strictEqual(expected.responseBody, Buffer.from(response.body, 'utf-8').toString('base64'));\n\n        assert.strictEqual(expected.requestId, JSON.parse(cdpFetchRequestPauseEvent).params.requestId);\n        assert.strictEqual(expected.wsEvent, 'message');\n        assert.deepEqual(expected.cdpCommands, ['Fetch.fulfillRequest', 'Fetch.enable', 'Network.setCacheDisabled']);\n      });\n  \n      client.start(done);\n    });\n  });\n\n  it('browser.mockNetworkResponse(urlToIntercept, {status, headers, body}) with multiple mocks', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const cdpCommandsExecuted = [];\n      let timesEventListenerAdded = 0;\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: () => {\n              timesEventListenerAdded++;\n            }\n          },\n          execute: function(command) {\n            cdpCommandsExecuted.push(command);\n          }\n        });\n      };\n\n      client.api.mockNetworkResponse('https://www.google.com/', {\n        status: 200,\n        headers: {'Content-Type': 'UTF-8'},\n        body: 'Hey there!'\n      });\n      client.api.mockNetworkResponse('https://www.duckduckgo.com/', {\n        status: 200,\n        headers: {'Content-Type': 'UTF-8'},\n        body: 'Good bye!'\n      });\n  \n      client.start(function (err) {\n        if (err) {\n          done(err);\n\n          return;\n        }\n\n        try {\n          const mocks = cdp.networkMocks;\n          assert.deepStrictEqual(Object.keys(mocks), ['https://www.google.com/', 'https://www.duckduckgo.com/']);\n          assert.strictEqual(mocks['https://www.google.com/'].body, Buffer.from('Hey there!').toString('base64'));\n          assert.strictEqual(mocks['https://www.duckduckgo.com/'].body, Buffer.from('Good bye!').toString('base64'));\n\n          assert.strictEqual(timesEventListenerAdded, 1);\n          assert.deepStrictEqual(cdpCommandsExecuted, ['Fetch.enable', 'Network.setCacheDisabled', 'Fetch.enable', 'Network.setCacheDisabled']);\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n  });\n\n  it('browser.mockNetworkResponse() with relative url to launch_url', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false,\n      launch_url: 'http://localhost:3000'\n    }).then(client => {\n      const expected = {\n        cdpCommands: []\n      };\n\n      // Parameters of actual request made by browser\n      const cdpFetchRequestPauseEvent = JSON.stringify({\n        method: 'Fetch.requestPaused',\n        params: {\n          requestId: '123',\n          request: {\n            url: 'http://localhost:3000/test_api'\n          }\n        }\n      });\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: (event, callback) => {\n              expected['wsEvent'] = event;\n              callback(cdpFetchRequestPauseEvent);\n            }\n          },\n          execute: function(command, params) {\n            expected.cdpCommands.push(command);\n            if (command === 'Fetch.fulfillRequest') {\n              expected['requestId'] = params.requestId;\n              expected['responseCode'] = params.responseCode;\n              expected['responseHeaders'] = params.responseHeaders;\n              expected['responseBody'] = params.body;\n            }\n          }\n        });\n      };\n\n      const response = {\n        status: 200,\n        body: 'Hey there!'\n      };\n      client.api.mockNetworkResponse('/test_api', response, function () {\n        // Assert final response with response passed\n        assert.strictEqual(expected.responseCode, response.status);\n        assert.deepEqual(expected.responseHeaders, []);\n        assert.strictEqual(expected.responseBody, Buffer.from(response.body, 'utf-8').toString('base64'));\n        assert.strictEqual(expected.requestId, JSON.parse(cdpFetchRequestPauseEvent).params.requestId);\n        assert.strictEqual(expected.wsEvent, 'message');\n        assert.deepEqual(expected.cdpCommands, ['Fetch.fulfillRequest', 'Fetch.enable', 'Network.setCacheDisabled']);\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('browser.mockNetworkResponse(urlToIntercept, {status, headers, body}) with url un-match', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {\n        cdpCommands: []\n      };\n\n      // Parameters of actual request made by browser\n      const cdpFetchRequestPauseEvent = JSON.stringify({\n        method: 'Fetch.requestPaused',\n        params: {\n          requestId: '123',\n          request: {\n            url: 'https://www.google.com/'\n          }\n        }\n      });\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: (event, callback) => {\n              expected['wsEvent'] = event;\n              callback(cdpFetchRequestPauseEvent);\n            }\n          },\n          execute: function(command, params) {\n            expected.cdpCommands.push(command);\n            if (command === 'Fetch.continueRequest') {\n              expected['requestId'] = params.requestId;\n            }\n          }\n        });\n      };\n\n      const response = {\n        status: 200,\n        headers: {'Content-Type': 'UTF-8'},\n        body: 'Hey there!'\n      };\n      client.api.mockNetworkResponse('https://www.yahoo.com/', response, function () {\n        // Request will not be intercepted, Fetch.continueRequest is called instead of Fetch.fulfillRequest\n        assert.strictEqual(expected.requestId, JSON.parse(cdpFetchRequestPauseEvent).params.requestId);\n        assert.strictEqual(expected.wsEvent, 'message');\n        assert.deepEqual(expected.cdpCommands, ['Fetch.continueRequest', 'Fetch.enable', 'Network.setCacheDisabled']);\n      });\n  \n      client.start(done);\n    });\n  });\n\n  it('browser.mockNetworkResponse(urlToIntercept, {})', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {\n        cdpCommands: []\n      };\n\n      // Parameters of actual request made by browser\n      const cdpFetchRequestPauseEvent = JSON.stringify({\n        method: 'Fetch.requestPaused',\n        params: {\n          requestId: '123',\n          request: {\n            url: 'https://www.google.com/'\n          }\n        }\n      });\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: (event, callback) => {\n              expected['wsEvent'] = event;\n              callback(cdpFetchRequestPauseEvent);\n            }\n          },\n          execute: function(command, params) {\n            expected.cdpCommands.push(command);\n            if (command === 'Fetch.fulfillRequest') {\n              expected['requestId'] = params.requestId;\n              expected['responseCode'] = params.responseCode;\n              expected['responseHeaders'] = params.responseHeaders;\n              expected['responseBody'] = params.body;\n            }\n          }\n        });\n      };\n\n      const response = {};\n      client.api.mockNetworkResponse('https://www.google.com/', response, function () {\n        // Assert final response with response passed\n        assert.strictEqual(expected.responseCode, 200);\n        assert.deepEqual(expected.responseHeaders, []);\n        assert.strictEqual(expected.responseBody, '');\n\n        assert.strictEqual(expected.requestId, JSON.parse(cdpFetchRequestPauseEvent).params.requestId);\n        assert.strictEqual(expected.wsEvent, 'message');\n        assert.deepEqual(expected.cdpCommands, ['Fetch.fulfillRequest', 'Fetch.enable', 'Network.setCacheDisabled']);\n      });\n  \n      client.start(done);\n    });\n  });\n\n  it('browser.mockNetworkResponse()', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {\n        cdpCommands: []\n      };\n\n      // Parameters of actual request made by browser\n      const cdpFetchRequestPauseEvent = JSON.stringify({\n        method: 'Fetch.requestPaused',\n        params: {\n          requestId: '123',\n          request: {\n            url: ''\n          }\n        }\n      });\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: (event, callback) => {\n              expected['wsEvent'] = event;\n              callback(cdpFetchRequestPauseEvent);\n            }\n          },\n          execute: function(command, params) {\n            expected.cdpCommands.push(command);\n            if (command === 'Fetch.fulfillRequest') {\n              expected['requestId'] = params.requestId;\n              expected['responseCode'] = params.responseCode;\n              expected['responseHeaders'] = params.responseHeaders;\n              expected['responseBody'] = params.body;\n            }\n          }\n        });\n      };\n\n      client.api.mockNetworkResponse(undefined, undefined, function() {\n        // Assert final response with response passed\n        assert.strictEqual(expected.responseCode, 200);\n        assert.deepEqual(expected.responseHeaders, []);\n        assert.strictEqual(expected.responseBody, '');\n\n        assert.strictEqual(expected.requestId, JSON.parse(cdpFetchRequestPauseEvent).params.requestId);\n        assert.strictEqual(expected.wsEvent, 'message');\n        assert.deepEqual(expected.cdpCommands, ['Fetch.fulfillRequest', 'Fetch.enable', 'Network.setCacheDisabled']);\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('browser.mockNetworkResponse - driver not supported', function(done){\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const response = {\n        status: 200,\n        headers: {'Content-Type': 'UTF-8'},\n        body: 'Hey there!'\n      };\n      client.api.mockNetworkResponse('https://www.google.com', response, function(result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .mockNetworkResponse() is only supported in Chrome and Edge drivers');\n      });\n      client.start(done);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testNavigateTo.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('.navigateTo()', function() {\n  describe('with backwards compat mode', function() {\n    before(function(done) {\n      CommandGlobals.beforeEach.call(this, done, {\n        backwards_compatibility_mode: true\n      });\n    });\n\n    after(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('browser.navigateTo(); relative url', function (done) {\n      this.client.api.baseUrl = 'http://localhost';\n      this.client.api.navigateTo('/homepage', result => {\n        assert.deepStrictEqual(result, {value: null, status: 0});\n      });\n\n      this.client.start(done);\n    });\n\n    it('browser.navigateTo(); relative url without baseUrl', function (done) {\n      this.client.api.baseUrl = null;\n      this.client.api.navigateTo('/homepage');\n\n      this.client.start(function(err) {\n        try {\n          assert.ok(err instanceof Error);\n          assert.strictEqual(err.message, 'Error while running \"navigateTo\" command: Invalid URL /homepage. When using relative uris, you must define a \"baseUrl\" or \"launchUrl\" in your nightwatch config.');\n          done();\n        } catch (e) {\n          done(e);\n        }\n\n      });\n    });\n\n    it('browser.navigateTo() - with url', function (done) {\n      this.client.api.navigateTo('http://localhost/test_url', result => {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n\n    it('browser.navigateTo() - with onBrowserNavigate global', function (done) {\n      let resultFromPerform;\n      let resultFromCallback;\n\n      this.client.settings.globals.onBrowserNavigate = async function(browser, result) {\n        resultFromPerform = await browser.perform(function() {\n          const resultCopy = Object.assign({}, result);\n          resultCopy.something = 'test-value';\n\n          return resultCopy;\n        });\n      };\n\n      this.client.api.navigateTo('http://localhost/test_url', result => {\n        resultFromCallback = result;\n\n        return result;\n      });\n\n      this.client.start(function(err) {\n        if (err) {\n          done(err);\n\n          return;\n        }\n\n        try {\n          assert.deepStrictEqual(resultFromCallback, {value: null, status: 0});\n          assert.deepStrictEqual(resultFromPerform, {value: null, status: 0, something: 'test-value'});\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n\n    it('browser.navigateTo() - with onBrowserNavigate global and default callback', function (done) {\n      let resultFromPerform;\n\n      this.client.settings.globals.onBrowserNavigate = async function(browser, result) {\n        resultFromPerform = await browser.perform(function() {\n          const resultCopy = Object.assign({}, result);\n          resultCopy.something = 'test-value';\n\n          return resultCopy;\n        });\n      };\n\n      this.client.api.navigateTo('http://localhost/test_url');\n\n      this.client.start(function(err) {\n        if (err) {\n          done(err);\n\n          return;\n        }\n\n        try {\n          assert.deepStrictEqual(resultFromPerform, {value: null, status: 0, something: 'test-value'});\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n  });\n\n  describe('without compat mode', function() {\n    before(function(done) {\n      CommandGlobals.beforeEach.call(this, done);\n    });\n\n    after(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('browser.navigateTo();', function (done) {\n      this.client.api.baseUrl = 'http://localhost';\n      this.client.api.navigateTo('/test_url', result => {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n\n    it('browser.navigateTo(); with error', function (done) {\n      this.client.api.navigateTo();\n\n      this.client.start(function(err) {\n        try {\n          assert.ok(err instanceof Error);\n          assert.strictEqual(err.message, 'Error while running \"navigateTo\" command: Missing url parameter.');\n          done();\n        } catch (e) {\n          done(e);\n        }\n      });\n    });\n\n    it('browser.navigateTo() - with url', function (done) {\n      this.client.api.navigateTo('http://localhost/test_url', result => {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testNightwatchRepl.js",
    "content": "const assert = require('assert');\nconst mockery = require('mockery');\nconst nodeRepl = require('repl');\nconst common = require('../../../../common.js');\n\ndescribe('startServer', function() {\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n  });\n\n  afterEach(function() {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n  });\n\n  it('with default config', function() {\n    let configUsed;\n    mockery.registerMock('repl', {\n      start(config) {\n        configUsed = config;\n\n        return 'repl';\n      }\n    });\n\n    let contextPassed;\n    mockery.registerMock('vm', {\n      createContext(context) {\n        contextPassed = context;\n      }\n    });\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n    const repl = new NightwatchRepl();\n\n    const context = {browser: 'something', app: 'other'};\n    repl.startServer(context);\n\n    assert.strictEqual(contextPassed, context);\n    assert.strictEqual(configUsed.preview, true);\n    assert.strictEqual(configUsed.timeout, 5500);\n\n    assert.strictEqual(repl._context, context);\n    assert.strictEqual(repl._replServer, 'repl');\n  });\n\n  it('with custom config', function() {\n    let configUsed;\n    mockery.registerMock('repl', {\n      start(config) {\n        configUsed = config;\n\n        return 'repl';\n      }\n    });\n\n    let contextPassed;\n    mockery.registerMock('vm', {\n      createContext(context) {\n        contextPassed = context;\n      }\n    });\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n\n    const config = {preview: false, timeout: 6000};\n    const repl = new NightwatchRepl(config);\n\n    const context = {browser: 'something'};\n    repl.startServer(context);\n\n    assert.strictEqual(contextPassed, context);\n    assert.strictEqual(configUsed.preview, false);\n    assert.strictEqual(configUsed.timeout, 6000);\n\n    assert.strictEqual(repl._context, context);\n    assert.strictEqual(repl._replServer, 'repl');\n  });\n});\n\ndescribe('_eval', function() {\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n  });\n\n  afterEach(function() {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n  });\n\n  it('calls _outputPreview if cmd represents auto-complete request', () => {\n    const NightwatchRepl = common.require('testsuite/repl.js');\n    const repl = new NightwatchRepl();\n\n    let outputPreviewCalled = false;\n    repl._outputPreview = () => {\n      outputPreviewCalled = true;\n    };\n    repl._eval('try { nightwatch } catch {}');\n\n    assert.strictEqual(outputPreviewCalled, true);\n  });\n\n  it('cmd not evaluated if result is awaited', function() {\n    let commandEvaluated = false;\n    mockery.registerMock('vm', {\n      runInContext() {\n        commandEvaluated = true;\n      }\n    });\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n    const repl = new NightwatchRepl();\n\n    repl._resultAwaited = true;\n    repl._eval('1+1');\n\n    assert.strictEqual(commandEvaluated, false);\n  });\n\n  it('cmd is evaluated correctly', function() {\n    mockery.registerMock('repl', {\n      start() {}\n    });\n\n    let handleResultCalled = false;\n    let resultObtained;\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n    const repl = new NightwatchRepl();\n\n    repl.startServer({});\n    repl._handleResult = (result) => {\n      handleResultCalled = true;\n      resultObtained = result;\n    };\n\n    repl._eval('1+1');\n\n    assert.strictEqual(handleResultCalled, true);\n    assert.strictEqual(resultObtained, 2);\n  });\n\n  it('logs error and calls callback for wrong cmd', function() {\n    mockery.registerMock('repl', {\n      start() {}\n    });\n\n    let errorLogged;\n    mockery.registerMock('../utils', {\n      Logger: class {\n        static error(err) {\n          errorLogged = err;\n        }\n      }\n    });\n\n    let callbackCalled = false;\n    let callbackErrorPassed;\n    let callbackResultPassed;\n    const callback = (error, result) => {\n      callbackCalled = true;\n      callbackErrorPassed = error;\n      callbackResultPassed = result;\n    };\n\n    let handleResultCalled = false;\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n    const repl = new NightwatchRepl();\n\n    repl.startServer({});\n    repl._handleResult = () => {\n      handleResultCalled = true;\n    };\n\n    repl._eval('random', undefined, undefined, callback);\n\n    assert.strictEqual(handleResultCalled, false);\n    assert.strictEqual(errorLogged.name, 'ReferenceError');\n    assert.strictEqual(callbackCalled, true);\n    assert.strictEqual(callbackErrorPassed, undefined);\n    assert.strictEqual(callbackResultPassed, undefined);\n  });\n\n  it('asks for more input if cmd is incomplete', function() {\n    mockery.registerMock('repl', {\n      start() {},\n      Recoverable: nodeRepl.Recoverable\n    });\n\n    let callbackCalled = false;\n    let callbackErrorPassed;\n    let callbackResultPassed;\n    const callback = (error, result) => {\n      callbackCalled = true;\n      callbackErrorPassed = error;\n      callbackResultPassed = result;\n    };\n\n    let handleResultCalled = false;\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n    const repl = new NightwatchRepl();\n\n    repl.startServer({});\n    repl._handleResult = () => {\n      handleResultCalled = true;\n    };\n\n    repl._eval('console.log(', undefined, undefined, callback);\n\n    assert.strictEqual(handleResultCalled, false);\n    assert.strictEqual(callbackCalled, true);\n    assert.strictEqual(callbackErrorPassed instanceof nodeRepl.Recoverable, true);\n    assert.strictEqual(callbackResultPassed, undefined);\n  });\n});\n\ndescribe('_handleResult', function() {\n  it('result is undefined', function() {\n    let errorReturned;\n    let resultReturned;\n    const callback = (error, result) => {\n      errorReturned = error;\n      resultReturned = result;\n    };\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n    const repl = new NightwatchRepl();\n    repl._handleResult(undefined, callback);\n\n    // Assertions are written in this fashion to make sure that the\n    // execution is synchronous (values are assigned to variables here).\n    assert.strictEqual(errorReturned, null);\n    assert.strictEqual(resultReturned, undefined);\n    assert.strictEqual(repl._resultAwaited, undefined);\n  });\n\n  it('result is non-promise', function() {\n    let errorReturned;\n    let resultReturned;\n    const callback = (error, result) => {\n      errorReturned = error;\n      resultReturned = result;\n    };\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n    const repl = new NightwatchRepl();\n    repl._handleResult('Google', callback);\n\n    assert.strictEqual(errorReturned, null);\n    assert.strictEqual(resultReturned, 'Google');\n    assert.strictEqual(repl._resultAwaited, undefined);\n  });\n\n  it('result is a promise resolved before timeout', function(done) {\n    const startTime = new Date();\n    let callbackCalledCount = 0;\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n\n    const config = {timeout: 1000};\n    const repl = new NightwatchRepl(config);\n\n    const result = new Promise((resolve) => {\n      setTimeout(() => {\n        resolve('something');\n      }, 500);\n    });\n    repl._handleResult(result, (error, result) => {\n      const timeElapsed = new Date() - startTime;\n      assert.ok(timeElapsed >= 500);\n      assert.ok(timeElapsed <= 600);\n\n      assert.strictEqual(error, null);\n      assert.strictEqual(result, 'something');\n      assert.strictEqual(repl._resultAwaited, false);\n\n      // This callback is only called once\n      callbackCalledCount++;\n      assert.strictEqual(callbackCalledCount, 1);\n    });\n\n    assert.strictEqual(repl._resultAwaited, true);\n\n    // Call done after the last possible call that can be\n    // made to callback passed into _handleResult.\n    setTimeout(() => {\n      done();\n    }, 1100);\n  });\n\n  it('result is a promise resolved after timeout', function(done) {\n    const startTime = new Date();\n    let callbackCalledCount = 0;\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n\n    const config = {timeout: 1000};\n    const repl = new NightwatchRepl(config);\n\n    const result = new Promise((resolve) => {\n      setTimeout(() => {\n        resolve('something');\n      }, 1500);\n    });\n    repl._handleResult(result, (error, result) => {\n      const timeElapsed = new Date() - startTime;\n      assert.ok(timeElapsed >= 1000);\n      assert.ok(timeElapsed <= 1100);\n\n      assert.strictEqual(error, undefined);\n      assert.strictEqual(result, undefined);\n      assert.strictEqual(repl._resultAwaited, false);\n\n      // This callback is only called once\n      callbackCalledCount++;\n      assert.strictEqual(callbackCalledCount, 1);\n    });\n\n    assert.strictEqual(repl._resultAwaited, true);\n\n    // Call done after the last possible call that can be\n    // made to callback passed into _handleResult.\n    setTimeout(() => {\n      done();\n    }, 1600);\n  });\n});\n\ndescribe('_outputPreview', () => {\n  it('calls callback with correct result if found', () => {\n    let callbackCalled = false;\n    let callbackErrorPassed;\n    let callbackResultPassed;\n    const callback = (error, result) => {\n      callbackCalled = true;\n      callbackErrorPassed = error;\n      callbackResultPassed = result;\n    };\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n    const repl = new NightwatchRepl();\n    repl._context = {\n      nightwatch: {\n        is: {\n          the: 'best'\n        }\n      }\n    };\n    repl._outputPreview('try { nightwatch.is.the } catch {}', callback);\n\n    assert.strictEqual(callbackCalled, true);\n    assert.strictEqual(callbackErrorPassed, null);\n    assert.strictEqual(callbackResultPassed, 'best');\n  });\n\n  it('does not call callback if command not resolvable', () => {\n    let callbackCalled = false;\n    let callbackErrorPassed;\n    let callbackResultPassed;\n    const callback = (error, result) => {\n      callbackCalled = true;\n      callbackErrorPassed = error;\n      callbackResultPassed = result;\n    };\n\n    const NightwatchRepl = common.require('testsuite/repl.js');\n    const repl = new NightwatchRepl();\n    repl._context = {\n      nightwatch: {\n        is: {\n          the: 'best'\n        }\n      }\n    };\n    repl._outputPreview('try { nightwatch.iss.the } catch {}', callback);\n\n    assert.strictEqual(callbackCalled, false);\n    assert.strictEqual(callbackErrorPassed, undefined);\n    assert.strictEqual(callbackResultPassed, undefined);\n  });\n});"
  },
  {
    "path": "test/src/api/commands/client/testPause.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst common = require('../../../../common.js');\n\ndescribe('.pause()', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.pause(10) pauses atleast 10ms and not more than 2000ms', function(done) {\n    const startTime = new Date();\n    this.client.api.pause(10, function() {\n      const timeElapsed = new Date() - startTime;\n      assert.ok(timeElapsed >= 10);\n    });\n\n    this.client.start(done);\n  });\n\n  it('browser.pause(0) does not pause more than 2000ms', function(done) {\n    const startTime = new Date();\n    this.client.api.pause(0, function() {\n      const timeElapsed = new Date() - startTime;\n      assert.ok(timeElapsed >= 0);\n    });\n\n    this.client.start(done);\n  });\n\n  it('browser.pause(200) pauses for atleast 200ms and not more than 2000ms', function(done) {\n    const startTime = new Date();\n    this.client.api.pause(200, function() {\n      const timeElapsed = new Date() - startTime;\n      assert.ok(timeElapsed >= 200);\n    });\n\n    this.client.start(done);\n  });\n\n  it('browser.pause() and then resume after 200 ms', function(done) {\n    const startTime = new Date();\n    this.client.api.pause(undefined, function() {\n      const timeElapsed = new Date() - startTime;\n      assert.ok(timeElapsed >= 200);\n    });\n\n    setTimeout(() => {\n      process.stdin.emit('keypress', null, {name: 'return'});\n    }, 200);\n\n    this.client.start(done);\n  });\n\n  it('browser.pause() and then resume after 1000 ms', function(done) {\n    const startTime = new Date();\n    this.client.api.pause(undefined, function() {\n      const timeElapsed = new Date() - startTime;\n      assert.ok(timeElapsed >= 1000);\n    });\n\n    setTimeout(() => {\n      process.stdin.emit('keypress', null, {name: 'return'});\n    }, 1000);\n\n    this.client.start(done);\n  });\n\n  it('browser.pause() and then step over using <space>', function(done) {\n    const Debuggability = common.require('utils/debuggability.js');\n\n    const startTime = new Date();\n\n    assert.strictEqual(Debuggability.stepOverAndPause, false);\n    this.client.api.pause(undefined, function() {\n      const timeElapsed = new Date() - startTime;\n      assert.ok(timeElapsed >= 200);\n      assert.strictEqual(Debuggability.stepOverAndPause, true);\n    });\n\n    setTimeout(() => {\n      process.stdin.emit('keypress', null, {name: 'space'});\n    }, 200);\n\n    this.client.start(done);\n  });\n\n  it('browser.pause() and then step over using F10', function(done) {\n    const Debuggability = common.require('utils/debuggability.js');\n\n    const startTime = new Date();\n\n    assert.strictEqual(Debuggability.stepOverAndPause, false);\n    this.client.api.pause(undefined, function() {\n      const timeElapsed = new Date() - startTime;\n      assert.ok(timeElapsed >= 200);\n      assert.strictEqual(Debuggability.stepOverAndPause, true);\n    });\n\n    setTimeout(() => {\n      process.stdin.emit('keypress', null, {name: 'f10'});\n    }, 200);\n\n    this.client.start(done);\n  });\n\n  it('browser.pause() and then exit', function(done) {\n    const clientApi = this.client.api;\n    const origEndFn = clientApi.end;\n\n    let apiEndCalledWithCallback = false;\n    let callbackCalled;\n    clientApi.end = (cb) => {\n      if (cb) {\n        apiEndCalledWithCallback = true;\n        callbackCalled = cb;\n      }\n    };\n    \n    const startTime = new Date();\n\n    this.client.api.pause(undefined, function() {\n      const timeElapsed = new Date() - startTime;\n      assert.ok(timeElapsed >= 200);\n      assert.strictEqual(apiEndCalledWithCallback, true);\n      assert.strictEqual(callbackCalled.toString().includes('process.exit(0)'), true);\n\n      clientApi.end = origEndFn;\n    });\n\n    setTimeout(() => {\n      process.stdin.emit('keypress', null, {ctrl: true, name: 'c'});\n    }, 200);\n\n    this.client.start(done);\n  });\n});"
  },
  {
    "path": "test/src/api/commands/client/testPerform.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('.perform()', function () {\n  beforeEach(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.perform()', function (done) {\n    let client = this.client.api;\n    this.client.api.perform(function () {\n      assert.deepStrictEqual(client.options, this.options);\n    });\n\n    this.client.start(done);\n  });\n\n  it('browser.perform() with async callback', async function () {\n    const result = await this.client.api.perform(function() {\n      return new Promise(resolve => {\n        setTimeout(function() {\n          resolve(100);\n        }, 50);\n      });\n    });\n\n    assert.strictEqual(result, 100);\n  });\n\n  it('browser.perform() with callback with \"done\" argument', function (done) {\n    this.client.api.perform(function (complete) {\n      assert.strictEqual(typeof complete, 'function');\n      complete();\n    });\n\n    this.client.start(done);\n  });\n\n  it('browser.perform() with async callback with \"browser\" and \"done\" arguments', function (done) {\n    let localClient = this.client.api;\n    this.client.api.perform(function (client, complete) {\n      delete client.isES6Async;\n      assert.deepEqual(localClient, client);\n      assert.strictEqual(typeof complete, 'function');\n      complete();\n    });\n\n    this.client.start(done);\n  });\n\n  it('test actions() options in browser.perform()', function (done) {\n    this.client.transport.driver.actions = function(opts) {\n      assert.deepStrictEqual(opts, {async: true});\n\n      return {\n        keyDown() {\n          return Promise.resolve();\n        }\n      };\n    };\n\n    this.client.api.perform(function() {\n      const actions = this.actions({async: true});\n\n      return actions.keyDown();\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testRegisterBasicAuth.js",
    "content": "const assert = require('assert');\nconst common = require('../../../../common.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst cdp = common.require('transport/selenium-webdriver/cdp.js');\n\ndescribe('.registerBasicAuth()', function () {\n  beforeEach(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.registerBasicAuth()', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      }\n    }).then(client => {\n      let expectedUsername;\n      let expectedPassword;\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve();\n      };\n      client.transport.driver.register = (username, password) => {\n        expectedUsername = username;\n        expectedPassword = password;\n      };\n\n      client.api.registerBasicAuth('nightwatch', 'BarnOwl', function (){\n        assert.strictEqual(expectedUsername, 'nightwatch');\n        assert.strictEqual(expectedPassword, 'BarnOwl');\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('browser.registerBasicAuth - driver not supported', function(done){\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    }).then(client => {\n      client.api.registerBasicAuth('admin', 'admin', function(result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .registerBasicAuth() is only supported in Chromium based drivers');\n      });\n\n      client.start(done);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testSaveScreenshot.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst common = require('../../../../common.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst {Screenshots} = common.require('utils');\n\ndescribe('.saveScreenshot()', function() {\n  before(function() {\n    this.writeScreenshotToFile = Screenshots.writeScreenshotToFile;\n  });\n\n  after(function() {\n    Screenshots.writeScreenshotToFile = this.writeScreenshotToFile;\n  });\n\n  describe('with backwards compat mode', function() {\n    before(function(done) {\n      CommandGlobals.beforeEach.call(this, done, {\n        backwards_compatibility_mode: true\n      });\n    });\n\n    after(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('browser.saveScreenshot()', function(done) {\n      const base64Image = 'iVBORw0KGgoAAAANSUhEUgAAAfQAAAH0CAIAAABEtEjdAAAACXBIWXMAAA7zAAAO8wEcU5k6AAAAEXRFWHRUaXRsZQBQREYgQ3JlYXRvckFevCgAAAATdEVYdEF1dGhvcgBQREYgVG9vbHMgQUcbz3cwAAAALXpUWHREZXNjcmlwdGlvbgAACJnLKCkpsNLXLy8v1ytISdMtyc/PKdZLzs8FAG6fCPGXryy4AAPW0ElEQVR42uy9Z5djV3Yl+ByAB+9deG8yMzLSMA1tkeWk6pJKKmla06MlafRB3/UX9BP0eTSj1RpperpLKpXKscgii0xDZpLpIyMiM7yPQCCAgLfPzr73AUikYVVR00sqUvcwVxABIICHB2Dfc/fZZx/eNE2OBQsWLFh8uUJgp4AFCxYsGLizYMGCBQsG7ixYsGDBgoE7CxYsWLBg4M6CBQsWLBi4s2DBggUDdxYsWLBgwcCdBQsWLFgwcGfBggULFgzcWbBgwYIFA3cWLFiwYODOggULFiwYuLNgwYIFCwbuLFiwYMGCgTsLFixYsGDgzoIFCxYsGLizYMGCBQN3FixYsGDBwJ0FCxYsWDBwZ8GCBQsWDNxZsGDBggUDdxYsWLBg4M6CBQsWLBi4s2DBggULBu4sWLBgwYKBOwsWLFiwYODOggULFiwYuLNgwYIFA3cWLFiwYMHAnQULFixYMHBnwYIFCxYM3FmwYMGCBQN3FixYsGDgzoIFCxYsGLizYMGCBQsG7ixYsGDBgoE7CxYsWLBg4M6CBQsWLBi4s2DBggUDdxYsWLBgwcCdBQsWLFgwcGfBggULFgzcWbBgwYIFA3cWLFiwYODOggULFiwYuLNgwYIFCwbuLFiwYMHi3zokdgpY/FuG/oLrjK4Uw+hc4lv315/LRfjnHsHsuoftcx0P/8Jrzc+4jOMRtBclRoLJvmAsGLizYPE0NAodTOe7LrdvE1/0R93Aavz/O5AXgTXf/tV8Fv6F5za7xnOLhMneXRa/AcGbJvsosvi3C/MzE2fjV68CvxI4+c8NrDynfs7MXnj+qF74pNbrEdlbzoKBOwuG9//KO3Tf9wlt8q9/ev7FsG7dXfocCwELFv9+wWgZFr95gG4+jZj85/rzz5us2D7XQ/DmZyO7yRCfBQN3Fv/Rd4yfAaKfdQ3/6yIm/znR1DQ/J/6an3EMJoNyFgzcWfyHTtnBRQv8Z+Hj8+DIW9y18auy6s5ffj51L99+SJP/9f/g107PGdazYODO4j9IGJ8NwDz/QgB/BtZ/Vd3V/JytG60nNZ7DYcN88YbC9vnwnQULBu4svmxJOo02cJPABc0E+hpmG8itO9DbeKF1TRfKc1YB06R/a3Ql2fxnpu0muaNp0IdrPSJn6hwv0T82n1tY+ObzGwfT1Dh6SO3lxTBNXSCPiOsIR28YTxYkXngW/s2uI2SYz+LfK5hahsW/aaifAXyarlkoL/K8wAtdH9DOUkF/FZ5K5+nyYX2GBfqAPK9a8NuGa6NLjai3wd1aKSwwtzW7l6MWYwTwFgR6hcF3HYxu6KLgemoBo/c1DIMcBw5eFAD3RmdN0XWHyPInFgzcWXyJQtM0viusjxl+6vyz2b1FqYiC+BRqI/nWdICmYMitnFzkhDZMA0sFke/gq6FTWBYI9Bs1DZCq0sAFC3ZxL6fTics4EjsNwDBnpfbNJidJFMrN9qPwLemLQZcOod23pJt4UdhIWFsQ63UJ1hrQtToYZFtC7mKR+IJpbTtYsGDgzuLLzdV05eFt1DO6eByd0iFdaKhKTzJ85Mi6oWpNTVNqtRruCbxuNtV6va40gekEu7VmQVGUZrOJx5IkyWazWc8CQG/SsK7Hrw6HAz9lIYBfRZvNulKWXaJNslYjySZw9vZBd/gc24s6Wk1B1VQAvSiypiUWDNxZ/IfC9A75bj5dNgXxoaumbogSxXTKihiqWqtVqtWq0mgUsgqSY4A+MB0ZuSCaokiwF6htAbTN5hAESeAlkYTk9ds5kpULLXaFPKbwJK+2lg1VVer1RqNBMvGGBz8B+vhVaaqaoSsktIaiOJ1up9tlkxx4XDwdLjudLldAtX7lke/zrWchFD9+7TgW6ISQAdbz0vNuBa1ShCAwzz4WDNxZ/Cah87MfoM/gHICYHe6iU00loVjceYd413FXQ1MqFaB5pVjIAdMB4gBuECn46fc4ZVkGhguiwYuWLZjB6SqBbItCMSnJTdQuFqPS3gdYdwC+k8fXBAvxAcG4gNeCw8NPkmi7WsuATqFfJLQLeUDcQTcB99VGvVrBPqGGBUCjqwHAnaT4suxBuH0ul1uw2w1VF/Dgkv3pHQpniuYzZ4mBOwsG7iy+wOBuPsc14xqwKKIuck2lRqC8ivQc/0jKrDZ8Pq/ssAEtfT6PwyUTFKYENieVwMdzkK80arrWaDarpXKhXC4eHBzoNEh2ziGVBsciI6HeP8yTB1QUJPVerxc/cRm8DdYJi64BFw909vl8yWQyEom47IROwaHq0PHwYG9ku0MGQyN7vXhUAtat9NzaByDr9+qNRqVSK5VK1Uodj6kjTzc5t9uL1cjr9fu8AZvLxVklAZPTRf3Z5e1FJ4cFCwbuLL4Y4N4J4C8gtU4DwFo/KIAxB8oDiP1+bzDkd/v9nN1GZTEGzcrh8quYzUaz3sD9d3ZvVCqlo6PD9FGqXC40mkDVQrFY4AWTgHWDVE3B0ABbkUQDynNVrkHDegpgukh5nHK5jF9xB0A58m/c2mJ1uENcQMJOrtQB5lhgfE7Z5fJ4w+FoNB4PBsOy0+V2u32+AH4K2jDJ90kNlspgNINTDVRac4VCuVQtFEpYPvCwfl/Q7/cju5ciLqEd7FPEgoE7i/+JqPzMG/55705YDqAX5Ilgx7mOGBEQTFkRvXU3qGDafUDIY1WTkxxcVatmq8fpUiFX0RqmW/YhsXX0V/0Br+TzcrxGOBlIF034MjY5Qctm9ra213Z21/cPd/P541qd8DPp7Gy9jnRbtwF3bU7Cm0gOu01G7gs0pul/DWAai8Wi0ShyZ87lQE5dLBZJkq5rQHbsBpBPA7sJiAuCpZ/Bz0qtCsRPF/cB2X5PSLa7eY1XGyrodggzRVMz1JqhVjijbhc1l8wHgq6A39c/RfYHHo8rEvZHo5FQwIdUnxPAFoGQcXCmzCmiWlRyx9VsJl8p1W3KqM/njiSCgbjEeaEKwvmsc4KC1B7HYZgSLzhxslRaHSCEUFuNyeMguCrPNSRk/4R7ElpPYbjJmTbaak77c+9s91vMd/d8WZeZNJOBO4svHbb/OkSARpnnTj8RmBGelAsNodNGBOk3pOOE7DaRkDtcpmroPAqikpszbWpVKx6Xq8Xa7va2XQKG28MhfyTs5X1ODuwzcNxxTPDF1Bvl6nE2nzrMHBwcHudKa2vrtYZWKVNyW4GMUgRSkww6OkAB2hcKRTxuv8PhlMHayG5JtBMuhagedaA2yByXy0XEKrLNKpAiWum5ywk4xj0hg+FoMYBKHE3sJPBkxUbDCSJGlrF0cLqmKyoKAKi4FnM5pVFp1spKs9qs15RGVcf1nHFU2IOuBkJMCHZUtely2qPRMDB+aGAw4Pci1Y8EQzanh6xtJASuqteL5XT6KHtcrDcNtyeQ6OmPxhKSbOPtdFXE2SXgDVTXsVuxO3wWEPOk19akHbcG7Yoi7BM1NZZasG7p9H+5PId/vqGXbSAYuLP4MibubeD4zC+8otEqI9+6lsIK/un0oUzak88T8Tcwx5Kdm3WAk6ma+Ux5Zzt1nC3JdmcgEBgfG7I7kWjqnIg7VMk/rgYdTKNR290/WFx4tLK8dZTO1xqm2hQ0FTR1xO0Mef0xlxwkjUK8zSl7oFcJDtWAz6BcgO9QxWChgVYFEI9dBCAbXAc+wLTCicsASgMcic1GDgyKF/x0OCRcj7xYsgqlBq2k0moraqNkATBlgb4UkkljaTOanIGfioryKRYZRcMrRYMrdg/1ah2bgVpToYuKWq/WiqV8sXBcrRY1BeR72Wbn3E7B55MjUd/gQHJkdDAej9qdJU4A0Hs5062V+KOjRi7brNVMrycYCAX9AbckQ3OpC7JJGrzI5BAvPfuC1W2L12uarQau1vtC8Bo7I4W+KbgcetHb3oXpz/gxMKqfgTuLLwu4Gy/+zj8B8KdCb19jWjDCQzwOeCD31SkrDR7burlZM4vFci2rZrPpfCHj9shDw8megSiYA86sgX8w1apuKEhzkeFu7+0uLi5ub29njyhX3gSQ8Xabyy67RcEJTUkgGA8Foz29Q6FgTBQdOrhsUYIM0RU6hqKQ4rhInl8jOhOUPSnYSRSvDdoaCuQzqACR3Bm/GUarJwk/UXaVHALdbLTkkVa9FtySRAU1LR8Z8P68Dg6KpwQUcnxdAwsFkaYNrak4ZkVRRZvYANAjCdegdzQb1drx8XGxkMXCoCrlSu0YBYJKLavrVZvdxH4gGFJARvX1Do6NTfX3jUj2AKcJWtMs5atH6eNcroADDvmDIRqCx8MpKsn6hbaqsu2JYPV64WhMQmc1DbISqHRCYejp9/RpA7XnnXYYuDNwZ/FlAffPHF7xwvzdmlkKAQhvWEJG0VIZilyrb1NXuEIeIpd6Hrz4cb7XNdI/EHYmLX6gyIkFTqwBfY4LqWwunz4qZdKV3d38/n5BU5CMe2VuiBQ2nQ7Q1h6vCz/dXpfsROVTsDsdbg9ELxIMBdCrRPNxCX2qlsEArdyCjhZstOHIklqS9QpaFXJrqwPWaXe2nQBE0hOl63QZIDVVof2KO+VN0gFLlgHDuhvfupIk8A67jOvB4ND2VyxxWNsMwteLNfIrTg9ZArBlQSmCnCKw/LpKKseNRimfz2SyB4X8cb1eVUzQULrTKURjgcH+2OBgvDcZDQZ8AuFtZMKhF7W9neP0QZ7nZK/L3z86jBICLztaPvMdfLfRAoipmeSNMemaDUYHzy0KTy3SAj1LfOsyA3cG7iy+rKF3jZ';\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/screenshot',\n        method: 'GET',\n        response: JSON.stringify({\n          sessionId: '1352110219202',\n          status: 0,\n          value: base64Image\n        })\n      }, true);\n\n      this.client.api.options.log_screenshot_data = false;\n\n      Screenshots.writeScreenshotToFile = async function(fileName, data, cb) {\n        assert.strictEqual(fileName, 'screenshot.png');\n        assert.strictEqual(data, base64Image);\n        \n        return fileName;\n      };\n\n      this.client.api.saveScreenshot('screenshot.png', function(result) {\n        assert.strictEqual(result.value, base64Image);\n        assert.strictEqual(result.suppressBase64Data, true);\n      });\n\n      this.client.start(done);\n    });\n  });\n\n  describe('without compat mode', function() {\n    before(function(done) {\n      CommandGlobals.beforeEach.call(this, done);\n    });\n\n    after(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('browser.saveScreenshot()', function(done) {\n      const base64Image = 'iVBORw0KGgoAAAANSUhEUgAAAfQAAAH0CAIAAABEtEjdAAAACXBIWXMAAA7zAAAO8wEcU5k6AAAAEXRFWHRUaXRsZQBQREYgQ3JlYXRvckFevCgAAAATdEVYdEF1dGhvcgBQREYgVG9vbHMgQUcbz3cwAAAALXpUWHREZXNjcmlwdGlvbgAACJnLKCkpsNLXLy8v1ytISdMtyc/PKdZLzs8FAG6fCPGXryy4AAPW0ElEQVR42uy9Z5djV3Yl+ByAB+9deG8yMzLSMA1tkeWk6pJKKmla06MlafRB3/UX9BP0eTSj1RpperpLKpXKscgii0xDZpLpIyMiM7yPQCCAgLfPzr73AUikYVVR00sqUvcwVxABIICHB2Dfc/fZZx/eNE2OBQsWLFh8uUJgp4AFCxYsGLizYMGCBQsG7ixYsGDBgoE7CxYsWLBg4M6CBQsWLBi4s2DBggUDdxYsWLBgwcCdBQsWLFgwcGfBggULFgzcWbBgwYIFA3cWLFiwYODOggULFiwYuLNgwYIFCwbuLFiwYMGCgTsLFixYsGDgzoIFCxYsGLizYMGCBQN3FixYsGDBwJ0FCxYsWDBwZ8GCBQsWDNxZsGDBggUDdxYsWLBg4M6CBQsWLBi4s2DBggULBu4sWLBgwYKBOwsWLFiwYODOggULFiwYuLNgwYIFA3cWLFiwYMHAnQULFixYMHBnwYIFCxYM3FmwYMGCBQN3FixYsGDgzoIFCxYsGLizYMGCBQsG7ixYsGDBgoE7CxYsWLBg4M6CBQsWLBi4s2DBggUDdxYsWLBgwcCdBQsWLFgwcGfBggULFgzcWbBgwYIFA3cWLFiwYODOggULFiwYuLNgwYIFCwbuLFiwYMHi3zokdgpY/FuG/oLrjK4Uw+hc4lv315/LRfjnHsHsuoftcx0P/8Jrzc+4jOMRtBclRoLJvmAsGLizYPE0NAodTOe7LrdvE1/0R93Aavz/O5AXgTXf/tV8Fv6F5za7xnOLhMneXRa/AcGbJvsosvi3C/MzE2fjV68CvxI4+c8NrDynfs7MXnj+qF74pNbrEdlbzoKBOwuG9//KO3Tf9wlt8q9/ev7FsG7dXfocCwELFv9+wWgZFr95gG4+jZj85/rzz5us2D7XQ/DmZyO7yRCfBQN3Fv/Rd4yfAaKfdQ3/6yIm/znR1DQ/J/6an3EMJoNyFgzcWfyHTtnBRQv8Z+Hj8+DIW9y18auy6s5ffj51L99+SJP/9f/g107PGdazYODO4j9IGJ8NwDz/QgB/BtZ/Vd3V/JytG60nNZ7DYcN88YbC9vnwnQULBu4svmxJOo02cJPABc0E+hpmG8itO9DbeKF1TRfKc1YB06R/a3Ql2fxnpu0muaNp0IdrPSJn6hwv0T82n1tY+ObzGwfT1Dh6SO3lxTBNXSCPiOsIR28YTxYkXngW/s2uI2SYz+LfK5hahsW/aaifAXyarlkoL/K8wAtdH9DOUkF/FZ5K5+nyYX2GBfqAPK9a8NuGa6NLjai3wd1aKSwwtzW7l6MWYwTwFgR6hcF3HYxu6KLgemoBo/c1DIMcBw5eFAD3RmdN0XWHyPInFgzcWXyJQtM0viusjxl+6vyz2b1FqYiC+BRqI/nWdICmYMitnFzkhDZMA0sFke/gq6FTWBYI9Bs1DZCq0sAFC3ZxL6fTics4EjsNwDBnpfbNJidJFMrN9qPwLemLQZcOod23pJt4UdhIWFsQ63UJ1hrQtToYZFtC7mKR+IJpbTtYsGDgzuLLzdV05eFt1DO6eByd0iFdaKhKTzJ85Mi6oWpNTVNqtRruCbxuNtV6va40gekEu7VmQVGUZrOJx5IkyWazWc8CQG/SsK7Hrw6HAz9lIYBfRZvNulKWXaJNslYjySZw9vZBd/gc24s6Wk1B1VQAvSiypiUWDNxZ/IfC9A75bj5dNgXxoaumbogSxXTKihiqWqtVqtWq0mgUsgqSY4A+MB0ZuSCaokiwF6htAbTN5hAESeAlkYTk9ds5kpULLXaFPKbwJK+2lg1VVer1RqNBMvGGBz8B+vhVaaqaoSsktIaiOJ1up9tlkxx4XDwdLjudLldAtX7lke/zrWchFD9+7TgW6ISQAdbz0vNuBa1ShCAwzz4WDNxZ/Cah87MfoM/gHICYHe6iU00loVjceYd413FXQ1MqFaB5pVjIAdMB4gBuECn46fc4ZVkGhguiwYuWLZjB6SqBbItCMSnJTdQuFqPS3gdYdwC+k8fXBAvxAcG4gNeCw8NPkmi7WsuATqFfJLQLeUDcQTcB99VGvVrBPqGGBUCjqwHAnaT4suxBuH0ul1uw2w1VF/Dgkv3pHQpniuYzZ4mBOwsG7iy+wOBuPsc14xqwKKIuck2lRqC8ivQc/0jKrDZ8Pq/ssAEtfT6PwyUTFKYENieVwMdzkK80arrWaDarpXKhXC4eHBzoNEh2ziGVBsciI6HeP8yTB1QUJPVerxc/cRm8DdYJi64BFw909vl8yWQyEom47IROwaHq0PHwYG9ku0MGQyN7vXhUAtat9NzaByDr9+qNRqVSK5VK1Uodj6kjTzc5t9uL1cjr9fu8AZvLxVklAZPTRf3Z5e1FJ4cFCwbuLL4Y4N4J4C8gtU4DwFo/KIAxB8oDiP1+bzDkd/v9nN1GZTEGzcrh8quYzUaz3sD9d3ZvVCqlo6PD9FGqXC40mkDVQrFY4AWTgHWDVE3B0ABbkUQDynNVrkHDegpgukh5nHK5jF9xB0A58m/c2mJ1uENcQMJOrtQB5lhgfE7Z5fJ4w+FoNB4PBsOy0+V2u32+AH4K2jDJ90kNlspgNINTDVRac4VCuVQtFEpYPvCwfl/Q7/cju5ciLqEd7FPEgoE7i/+JqPzMG/55705YDqAX5Ilgx7mOGBEQTFkRvXU3qGDafUDIY1WTkxxcVatmq8fpUiFX0RqmW/YhsXX0V/0Br+TzcrxGOBlIF034MjY5Qctm9ra213Z21/cPd/P541qd8DPp7Gy9jnRbtwF3bU7Cm0gOu01G7gs0pul/DWAai8Wi0ShyZ87lQE5dLBZJkq5rQHbsBpBPA7sJiAuCpZ/Bz0qtCsRPF/cB2X5PSLa7eY1XGyrodggzRVMz1JqhVjijbhc1l8wHgq6A39c/RfYHHo8rEvZHo5FQwIdUnxPAFoGQcXCmzCmiWlRyx9VsJl8p1W3KqM/njiSCgbjEeaEKwvmsc4KC1B7HYZgSLzhxslRaHSCEUFuNyeMguCrPNSRk/4R7ElpPYbjJmTbaak77c+9s91vMd/d8WZeZNJOBO4svHbb/OkSARpnnTj8RmBGelAsNodNGBOk3pOOE7DaRkDtcpmroPAqikpszbWpVKx6Xq8Xa7va2XQKG28MhfyTs5X1ODuwzcNxxTPDF1Bvl6nE2nzrMHBwcHudKa2vrtYZWKVNyW4GMUgRSkww6OkAB2hcKRTxuv8PhlMHayG5JtBMuhagedaA2yByXy0XEKrLNKpAiWum5ywk4xj0hg+FoMYBKHE3sJPBkxUbDCSJGlrF0cLqmKyoKAKi4FnM5pVFp1spKs9qs15RGVcf1nHFU2IOuBkJMCHZUtely2qPRMDB+aGAw4Pci1Y8EQzanh6xtJASuqteL5XT6KHtcrDcNtyeQ6OmPxhKSbOPtdFXE2SXgDVTXsVuxO3wWEPOk19akHbcG7Yoi7BM1NZZasG7p9H+5PId/vqGXbSAYuLP4MibubeD4zC+8otEqI9+6lsIK/un0oUzak88T8Tcwx5Kdm3WAk6ma+Ux5Zzt1nC3JdmcgEBgfG7I7kWjqnIg7VMk/rgYdTKNR290/WFx4tLK8dZTO1xqm2hQ0FTR1xO0Mef0xlxwkjUK8zSl7oFcJDtWAz6BcgO9QxWChgVYFEI9dBCAbXAc+wLTCicsASgMcic1GDgyKF/x0OCRcj7xYsgqlBq2k0moraqNkATBlgb4UkkljaTOanIGfioryKRYZRcMrRYMrdg/1ah2bgVpToYuKWq/WiqV8sXBcrRY1BeR72Wbn3E7B55MjUd/gQHJkdDAej9qdJU4A0Hs5062V+KOjRi7brNVMrycYCAX9AbckQ3OpC7JJGrzI5BAvPfuC1W2L12uarQau1vtC8Bo7I4W+KbgcetHb3oXpz/gxMKqfgTuLLwu4Gy/+zj8B8KdCb19jWjDCQzwOeCD31SkrDR7burlZM4vFci2rZrPpfCHj9shDw8megSiYA86sgX8w1apuKEhzkeFu7+0uLi5ub29njyhX3gSQ8Xabyy67RcEJTUkgGA8Foz29Q6FgTBQdOrhsUYIM0RU6hqKQ4rhInl8jOhOUPSnYSRSvDdoaCuQzqACR3Bm/GUarJwk/UXaVHALdbLTkkVa9FtySRAU1LR8Z8P68Dg6KpwQUcnxdAwsFkaYNrak4ZkVRRZvYANAjCdegdzQb1drx8XGxkMXCoCrlSu0YBYJKLavrVZvdxH4gGFJARvX1Do6NTfX3jUj2AKcJWtMs5atH6eNcroADDvmDIRqCx8MpKsn6hbaqsu2JYPV64WhMQmc1DbISqHRCYejp9/RpA7XnnXYYuDNwZ/FlAffPHF7xwvzdmlkKAQhvWEJG0VIZilyrb1NXuEIeIpd6Hrz4cb7XNdI/EHYmLX6gyIkFTqwBfY4LqWwunz4qZdKV3d38/n5BU5CMe2VuiBQ2nQ7Q1h6vCz/dXpfsROVTsDsdbg9ELxIMBdCrRPNxCX2qlsEArdyCjhZstOHIklqS9QpaFXJrqwPWaXe2nQBE0hOl63QZIDVVof2KO+VN0gFLlgHDuhvfupIk8A67jOvB4ND2VyxxWNsMwteLNfIrTg9ZArBlQSmCnCKw/LpKKseNRimfz2SyB4X8cb1eVUzQULrTKURjgcH+2OBgvDcZDQZ8AuFtZMKhF7W9neP0QZ7nZK/L3z86jBICLztaPvMdfLfRAoipmeSNMemaDUYHzy0KTy3SAj1LfOsyA3cG7iy+rKF3jZ';\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/screenshot',\n        method: 'GET',\n        response: JSON.stringify({\n          sessionId: '1352110219202',\n          status: 0,\n          value: base64Image\n        })\n      }, true);\n\n      this.client.api.options.log_screenshot_data = false;\n\n      Screenshots.writeScreenshotToFile = async function(fileName, data, cb) {\n        assert.strictEqual(fileName, 'screenshot.png');\n        assert.strictEqual(data, base64Image);\n\n        return fileName;\n      };\n\n      this.client.api.saveScreenshot('screenshot.png', function(result) {\n        assert.strictEqual(result.value, base64Image);\n        assert.strictEqual(result.suppressBase64Data, true);\n      });\n\n      this.client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testSaveSnapshot.js",
    "content": "const assert = require('assert');\nconst common = require('../../../../common.js');\nconst Nocks = require('../../../../lib/nocks');\nconst Utils = common.require('utils');\nconst CommandGlobals = require('../../../../lib/globals/commands');\n\ndescribe('.saveSnapshot()', function() {\n  before(function(done) {\n    this.writetToFile = Utils.writeToFile;\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  this.beforeEach(function() {\n    Nocks.enable();\n    Nocks.cleanAll();\n  });\n\n  after(function(done) {\n    Utils.writeToFile = this.writeToFile;\n    Nocks.disable();\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.saveScreenshot()', function(done) {\n    const pageHtml = '<!doctype html><html class=\"no-js\" lang=\"\"><head> <meta charset=\"utf-8\"> <title></title> <meta name=\"description\" content=\"\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <meta property=\"og:title\" content=\"\"> <meta property=\"og:type\" content=\"\"> <meta property=\"og:url\" content=\"\"> <meta property=\"og:image\" content=\"\"> <link rel=\"manifest\" href=\"site.webmanifest\"> <link rel=\"apple-touch-icon\" href=\"icon.png\"> <link rel=\"stylesheet\" href=\"css/normalize.css\"> <link rel=\"stylesheet\" href=\"css/main.css\"> <meta name=\"theme-color\" content=\"#fafafa\"></head><body> <p>Hello world! This is HTML5 Boilerplate.</p><script src=\"js/vendor/modernizr-3.11.2.min.js\"></script> <script src=\"js/plugins.js\"></script> <script src=\"js/main.js\"></script> <script>window.ga=function (){ga.q.push(arguments)}; ga.q=[]; ga.l=+new Date; ga(\\'create\\', \\'UA-XXXXX-Y\\', \\'auto\\'); ga(\\'set\\', \\'anonymizeIp\\', true); ga(\\'set\\', \\'transport\\', \\'beacon\\'); ga(\\'send\\', \\'pageview\\') </script> <script src=\"https://www.google-analytics.com/analytics.js\" async></script></body></html>';\n    const pageHtmlWithoutScript = '<!DOCTYPE html><html class=\"no-js\" lang=\"\"><head> <meta charset=\"utf-8\"> <title></title> <meta name=\"description\" content=\"\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <meta property=\"og:title\" content=\"\"> <meta property=\"og:type\" content=\"\"> <meta property=\"og:url\" content=\"\"> <meta property=\"og:image\" content=\"\"> <link rel=\"manifest\" href=\"site.webmanifest\"> <link rel=\"apple-touch-icon\" href=\"icon.png\"> <link rel=\"stylesheet\" href=\"css/normalize.css\"> <link rel=\"stylesheet\" href=\"css/main.css\"> <meta name=\"theme-color\" content=\"#fafafa\"></head><body> <p>Hello world! This is HTML5 Boilerplate.</p>    </body></html>';\n    const pageUrl = 'https://nightwatchjs.org';\n\n    Nocks.getUrl(pageUrl);\n    Nocks.getPageSource(pageHtml);\n\n    Utils.writeToFile = async function(fileName, data) {\n      assert.strictEqual(fileName, 'snapshot.html');\n      assert.strictEqual(data, pageHtmlWithoutScript);\n\n      return fileName;\n    };\n\n    this.client.api.saveSnapshot('snapshot.html', function(result) {\n      assert.ok(result);\n      assert.deepStrictEqual(result, {snapshotFilePath: 'snapshot.html',\n        snapshotUrl: pageUrl});\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testSetDeviceDimensions.js",
    "content": "const assert = require('assert');\nconst common = require('../../../../common.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst cdp = common.require('transport/selenium-webdriver/cdp.js');\n\ndescribe('.setDeviceDimensions()', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('should set device dimensions when all four properties are provided', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {};\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          execute: function(command, metrics) {\n            expected['cdpCommand'] = command;\n            expected['width'] = metrics.width;\n            expected['height'] = metrics.height;\n            expected['deviceScaleFactor'] = metrics.deviceScaleFactor;\n            expected['mobile'] = metrics.mobile;\n          }\n        });\n      };\n      client.api.setDeviceDimensions({width: 400, height: 600, deviceScaleFactor: 50, mobile: true}, function (){\n        assert.strictEqual(expected.cdpCommand, 'Emulation.setDeviceMetricsOverride');\n        assert.strictEqual(expected.width, 400);\n        assert.strictEqual(expected.height, 600);\n        assert.strictEqual(expected.deviceScaleFactor, 50);\n        assert.strictEqual(expected.mobile, true);\n      });\n      client.start(done);\n    });\n  });\n\n  it('should set device dimensions when just any two properties are provided', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {};\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          execute: function(command, metrics) {\n            expected['cdpCommand'] = command;\n            expected['width'] = metrics.width;\n            expected['height'] = metrics.height;\n            expected['deviceScaleFactor'] = metrics.deviceScaleFactor;\n            expected['mobile'] = metrics.mobile;\n          }\n        });\n      };\n      client.api.setDeviceDimensions({width: 400, deviceScaleFactor: 100}, function (){\n        assert.strictEqual(expected.cdpCommand, 'Emulation.setDeviceMetricsOverride');\n        assert.strictEqual(expected.width, 400);\n        assert.strictEqual(expected.height, 0);\n        assert.strictEqual(expected.deviceScaleFactor, 100);\n        assert.strictEqual(expected.mobile, false);\n      });\n      client.start(done);\n    });\n  });\n\n  it('should clear the device dimensions override when no property is provided', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {};\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          execute: function(command, metrics) {\n            expected['cdpCommand'] = command;\n            expected['metrics'] = metrics;\n          }\n        });\n      };\n\n      client.api.setDeviceDimensions({}, function () {\n        assert.strictEqual(expected.cdpCommand, 'Emulation.setDeviceMetricsOverride');\n        assert.deepEqual(expected.metrics, {deviceScaleFactor: 0, height: 0, mobile: false, width: 0});\n      });\n\n      // Checks if setDeviceDimensions work (doesn't throw error) with not argument at all.\n      client.api.setDeviceDimensions();\n\n      client.start(done);\n    });\n  });\n\n  it('browser.setDeviceDimensions - driver not supported', function(done){\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      client.api.setDeviceDimensions({width: 400, height: 600, deviceScaleFactor: 50}, function(result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .setDeviceDimensions() is only supported in Chrome and Edge drivers');\n      });\n      client.start(done);\n    });\n  });\n\n}); "
  },
  {
    "path": "test/src/api/commands/client/testSetGeolocation.js",
    "content": "const assert = require('assert');\nconst common = require('../../../../common.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst cdp = common.require('transport/selenium-webdriver/cdp.js');\n\ndescribe('.setGeolocation()', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('should mock geolocation when all three parameters are provided.', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {};\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          execute: function(command, coordinates) {\n            expected['cdpCommand'] = command;\n            expected['latitude'] = coordinates.latitude;\n            expected['longitude'] = coordinates.longitude;\n            expected['accuracy'] = coordinates.accuracy;\n          }\n        });\n      };\n      client.api.setGeolocation({latitude: 35.689487, longitude: 139.691706, accuracy: 55}, function (){\n        assert.strictEqual(expected.cdpCommand, 'Emulation.setGeolocationOverride');\n        assert.strictEqual(expected.latitude, 35.689487);\n        assert.strictEqual(expected.longitude, 139.691706);\n        assert.strictEqual(expected.accuracy, 55);\n      });\n      client.start(done);\n    });\n  });\n\n  it('should mock geolocation when just latitude and longitude is provided (accuracy default to 100)', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {};\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          execute: function(command, coordinates) {\n            expected['cdpCommand'] = command;\n            expected['latitude'] = coordinates.latitude;\n            expected['longitude'] = coordinates.longitude;\n            expected['accuracy'] = coordinates.accuracy;\n          }\n        });\n      };\n      client.api.setGeolocation({latitude: 35.689487, longitude: 139.691706}, function (){\n        assert.strictEqual(expected.cdpCommand, 'Emulation.setGeolocationOverride');\n        assert.strictEqual(expected.latitude, 35.689487);\n        assert.strictEqual(expected.longitude, 139.691706);\n        assert.strictEqual(expected.accuracy, 100);\n      });\n      client.start(done);\n    });\n  });\n\n  it('should throw an error when just either of latitude and longitude are provided', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      client.api.setGeolocation({longitude: 139.691706}, function (result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'Please provide both latitude and longitude while using setGeolocation.');\n      });\n      client.start(done);\n    });\n  });\n\n  it('should clear the geolocation override', function (done) {\n\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      const expected = {};\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          execute: function(command, coordinates) {\n            expected['cdpCommand'] = command;\n            expected['coordinates'] = coordinates;\n          }\n        });\n      };\n\n      client.api.setGeolocation({}, function (){\n        assert.strictEqual(expected.cdpCommand, 'Emulation.clearGeolocationOverride');\n        assert.deepEqual(expected.coordinates, {});\n      });\n\n      client.api.setGeolocation({accuracy: 50}, function (){\n        assert.strictEqual(expected.cdpCommand, 'Emulation.clearGeolocationOverride');\n        assert.deepEqual(expected.coordinates, {});\n      });\n\n      // Checks if setGeolocation works (doesn't throw error) with not argument at all.\n      client.api.setGeolocation();\n\n      client.start(done);\n    });\n  });\n\n  it('browser.setGeolocation - driver not supported', function(done){\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      client.api.setGeolocation({latitude: 35.689487, longitude: 139.691706, accuracy: 55}, function(result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .setGeolocation() is only supported in Chrome and Edge drivers');\n      });\n      client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testSetNetworkConditions.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\n\ndescribe('.setNetworkConditions()', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.setNetworkConditions()', function (done) {\n    MockServer.addMock(\n      {\n        url: '/session',\n        response: {\n          value: {\n            sessionId: '13521-10219-202',\n            capabilities: {\n              browserName: 'chrome',\n              browserVersion: '92.0'\n            }\n          }\n        },\n        method: 'POST',\n        statusCode: 201\n      },\n      true\n    );\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      }\n    }).then((client) => {\n      client.transport.driver.setNetworkConditions = function (spec) {\n        assert.strictEqual('download_throughput', 460800);\n        assert.strictEqual('latency', 50000);\n        assert.strictEqual('offline', false);\n        assert.strictEqual('upload_throughput', 153600);\n\n        return Promise.resolve();\n      };\n      client.api.setNetworkConditions({\n        offline: false,\n        latency: 50000,\n        download_throughput: 450 * 1024,\n        upload_throughput: 150 * 1024\n      },\n      function (result) {\n        assert.deepStrictEqual(result.value, null);\n      }\n      );\n      client.start(done);\n    });\n  });\n\n\n  it('browser.network.setConditions()', function (done) {\n    MockServer.addMock(\n      {\n        url: '/session',\n        response: {\n          value: {\n            sessionId: '13521-10219-202',\n            capabilities: {\n              browserName: 'chrome',\n              browserVersion: '92.0'\n            }\n          }\n        },\n        method: 'POST',\n        statusCode: 201\n      },\n      true\n    );\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then((client) => {\n      const expected = {};\n      client.transport.driver.setNetworkConditions = function (spec) {\n        expected['download_throughput'] = spec.download_throughput;\n        expected['latency'] = spec.latency;\n        expected['offline'] = spec.offline;\n        expected['upload_throughput'] = spec.upload_throughput;\n\n        return Promise.resolve();\n      };\n\n      client.api.network.setConditions({\n        offline: false,\n        latency: 50000,\n        download_throughput: 450 * 1024,\n        upload_throughput: 150 * 1024\n      },\n      function (result) {\n        expected['callback_result'] = result.value;\n      });\n\n      client.start(function (err) {\n        try {\n          assert.strictEqual(err, undefined);\n          assert.strictEqual(expected.callback_result, null);\n          assert.strictEqual(expected.download_throughput, 460800);\n          assert.strictEqual(expected.latency, 50000);\n          assert.strictEqual(expected.offline, false);\n          assert.strictEqual(expected.upload_throughput, 153600);\n          done();\n        } catch (e){\n          done(e);\n        }\n      });\n    });\n  });\n\n  it('browser.setNetworkConditions - driver not supported', function (done) {\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    }).then((client) => {\n      client.api.setNetworkConditions({\n        offline: false,\n        latency: 50000,\n        download_throughput: 450 * 1024,\n        upload_throughput: 150 * 1024\n      },\n      function (result) {\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .setNetworkConditions() is only supported in Chromium based drivers');\n      }\n      );\n      client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testTakeHeapSnapshot.js",
    "content": "const assert = require('assert');\nconst common = require('../../../../common.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst fs = require('fs');\nconst cdp = common.require('transport/selenium-webdriver/cdp.js');\n\ndescribe('.takeHeapSnapshot()', function(done) {\n  const origFsWriteFileSync = fs.writeFileSync;\n\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    fs.writeFileSync = origFsWriteFileSync;\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.takeHeapSnapshot(heapSnapshotLocation)', function(done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      }\n    }).then(client => {\n      const expected = {\n        cdpCommands: []\n      };\n\n      // Parameters of actual request made by browser\n      const cdpAddHeapSnapshotChunkEvent = JSON.stringify({\n        method: 'HeapProfiler.addHeapSnapshotChunk',\n        params: {\n          chunk: 'hello123'\n        }\n      });\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: (event, callback) => {\n              expected['wsEvent'] = event;\n              callback(cdpAddHeapSnapshotChunkEvent);\n            }\n          },\n          execute: function(command, params) {\n            expected.cdpCommands.push(command);\n            assert.deepEqual(params, {});\n          }\n        });\n      };\n\n      fs.writeFileSync = (filename, content) => {\n        expected['heapSnapshotLocation'] = filename;\n        expected['heapSnapshotContent'] = content;\n      };\n\n      const heapsnapshotLocation = 'snap.heapsnapshot';\n      client.api.takeHeapSnapshot(heapsnapshotLocation, function () {\n        assert.strictEqual(expected.heapSnapshotLocation, heapsnapshotLocation);\n        assert.strictEqual(expected.heapSnapshotContent, JSON.parse(cdpAddHeapSnapshotChunkEvent).params.chunk);\n        assert.strictEqual(expected.wsEvent, 'message');\n        assert.deepEqual(expected.cdpCommands, ['HeapProfiler.enable', 'HeapProfiler.takeHeapSnapshot']);\n      });\n  \n      client.start(done);\n    });\n  });\n\n  it('browser.takeHeapSnapshot(undefined, callback)', function(done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      }\n    }).then(client => {\n      const expected = {\n        cdpCommands: []\n      };\n\n      // Parameters of actual request made by browser\n      const cdpAddHeapSnapshotChunkEvent = JSON.stringify({\n        method: 'HeapProfiler.addHeapSnapshotChunk',\n        params: {\n          chunk: 'hello123'\n        }\n      });\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve({\n          _wsConnection: {\n            on: (event, callback) => {\n              expected['wsEvent'] = event;\n              callback(cdpAddHeapSnapshotChunkEvent);\n            }\n          },\n          execute: function(command, params) {\n            expected.cdpCommands.push(command);\n            assert.deepEqual(params, {});\n          }\n        });\n      };\n\n      fs.writeFileSync = (filename, content) => {\n        expected['heapSnapshotLocation'] = filename;\n        expected['heapSnapshotContent'] = content;\n      };\n\n      client.api.takeHeapSnapshot(undefined, function (result) {\n        // fs.writeFileSync was never called\n        assert.strictEqual(expected.heapSnapshotLocation, undefined);\n        assert.strictEqual(expected.heapSnapshotContent, undefined);\n\n        // Heap snapshot is passed as an argument to callback\n        assert.strictEqual(result.value, JSON.parse(cdpAddHeapSnapshotChunkEvent).params.chunk);\n\n        assert.strictEqual(expected.wsEvent, 'message');\n        assert.deepEqual(expected.cdpCommands, ['HeapProfiler.enable', 'HeapProfiler.takeHeapSnapshot']);\n      });\n  \n      client.start(done);\n    });\n  });\n\n  it('browser.takeHeapSnapshot - driver not supported', function(done) {\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    }).then(client => {\n      client.api.takeHeapSnapshot('snap.heapsnapshot', function(result) {\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .takeHeapSnapshot() is only supported in Chrome and Edge drivers');\n      });\n      client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/client/testWaitUntil.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('.waitUntil()', function () {\n  describe('with backwards compat mode', function() {\n    beforeEach(function (done) {\n      CommandGlobals.beforeEach.call(this, done, {\n        backwards_compatibility_mode: true,\n        globals: {\n          waitForConditionPollInterval: 50,\n          waitForConditionTimeout: 500\n        }\n      });\n    });\n\n    afterEach(function (done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('client.waitUntil() success with defaults', function (done) {\n      this.client.api.waitUntil(function () {\n        return new Promise(function(resolve) {\n          setTimeout(function() {\n            resolve(true);\n          }, 100);\n        });\n      }, function(result) {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n  });\n\n\n  describe('without compat mode', function() {\n    beforeEach(function (done) {\n      CommandGlobals.beforeEach.call(this, done, {\n        globals: {\n          waitForConditionPollInterval: 50,\n          waitForConditionTimeout: 500\n        }\n      });\n    });\n\n    afterEach(function (done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('client.waitUntil() success with defaults', function (done) {\n      this.client.api.waitUntil(function () {\n        return new Promise(function(resolve) {\n          setTimeout(function() {\n            resolve(true);\n          }, 100);\n        });\n      }, function(result) {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.waitUntil() function success with defaults', function (done) {\n      let tries = 0;\n      const client = this.client.api;\n\n      this.client.api.waitUntil(function () {\n        assert.deepStrictEqual(this.options, client.options);\n        if (tries > 5) {\n          return true;\n        }\n\n        tries++;\n\n        return false;\n      }, function(result) {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.waitUntil() function failure with defaults', function (done) {\n      const client = this.client.api;\n\n      this.client.api.waitUntil(function () {\n        assert.deepStrictEqual(this.options, client.options);\n\n        return false;\n      }, function(result) {\n        assert.strictEqual(result.status, -1);\n      });\n\n      this.client.start(function(err) {\n        try {\n          assert.ok(err instanceof Error);\n          assert.ok(err.message.includes('Error while running \"waitUntil\" command: [TimeoutError] Wait timed out after'), 'Should include: ' + err.message);\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n\n    it('client.waitUntil() function failure with custom timeout', function (done) {\n      let tries = 0;\n      const startTime = new Date().valueOf();\n      let timeDiff;\n      const maxTimeout = 100;\n      const client = this.client.api;\n      let result;\n\n      this.client.api.waitUntil(function () {\n        assert.deepStrictEqual(this.options, client.options);\n        tries++;\n\n        return false;\n      }, maxTimeout, 50, function(response) {\n        timeDiff = new Date().valueOf() - startTime;\n        result = response;\n      });\n\n      this.client.start(err => {\n        try {\n          assert.ok(timeDiff <= maxTimeout + 100, `Expected lower than ${maxTimeout}, but got ${timeDiff}`);\n          assert.strictEqual(result.status, -1);\n          assert.strictEqual(tries, 3);\n          assert.ok(err instanceof Error);\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n\n    it('client.waitUntil() function failure with custom timeout, interval, message, and callback', function (done) {\n      let tries = 0;\n      const startTime = new Date().valueOf();\n      let timeDiff;\n      const maxTimeout = 100;\n      const client = this.client.api;\n      let result;\n\n      this.client.api.waitUntil(function () {\n        assert.deepStrictEqual(this.options, client.options);\n        tries++;\n\n        return false;\n      }, maxTimeout, 50, 'custom error message', function(response) {\n        timeDiff = new Date().valueOf() - startTime;\n        result = response;\n      });\n\n      this.client.start(err => {\n        try {\n          assert.ok(timeDiff <= maxTimeout + 100, `Expected lower than ${maxTimeout}, but got ${timeDiff}`);\n          assert.strictEqual(result.status, -1);\n          assert.ok(err instanceof Error);\n          const messageParts = err.message.split('\\n');\n          assert.strictEqual(messageParts[0], 'Error while running \"waitUntil\" command: [TimeoutError] custom error message');\n          assert.ok(messageParts[1].startsWith('Wait timed out after'));\n\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n\n    it('client.waitUntil() function failure with custom timeout, interval, message', function (done) {\n      let tries = 0;\n      const maxTimeout = 100;\n      const client = this.client.api;\n\n      this.client.api.waitUntil(function () {\n        assert.deepStrictEqual(this.options, client.options);\n        tries++;\n\n        return false;\n      }, maxTimeout, 50, 'custom error message');\n\n      this.client.start(err => {\n        try {\n          assert.ok(err instanceof Error);\n          const messageParts = err.message.split('\\n');\n          assert.strictEqual(messageParts[0], 'Error while running \"waitUntil\" command: [TimeoutError] custom error message');\n          assert.ok(messageParts[1].startsWith('Wait timed out after'));\n\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n\n    it('client.waitUntil() function failure with custom timeout and default interval', function (done) {\n      let tries = 0;\n      const startTime = new Date().valueOf();\n      let timeDiff;\n      const maxTimeout = 100;\n      const client = this.client.api;\n      let result;\n\n      this.client.api.waitUntil(function () {\n        assert.deepStrictEqual(this.options, client.options);\n        tries++;\n\n        return false;\n      }, maxTimeout, function(response) {\n        timeDiff = new Date().valueOf() - startTime;\n        result = response;\n      });\n\n      this.client.start(err => {\n        try {\n          assert.ok(err instanceof Error);\n          assert.ok(timeDiff <= maxTimeout + 100, `Expected lower than ${maxTimeout}, but got ${timeDiff}`);\n          assert.strictEqual(result.status, -1);\n          assert.strictEqual(tries, 3);\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n\n    it('client.waitUntil() function with nightwatch perform() command', function (done) {\n      this.client.api.waitUntil(async function () {\n        const result = await this.perform(function() {\n          return 1;\n        });\n\n        return result === 1;\n      }, 100, function(result) {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.waitUntil() function with nightwatch perform() command and Promise', function (done) {\n      this.client.api.waitUntil(async function () {\n        const result = await this.perform(async function() {\n          return 10;\n        });\n\n        return result === 10;\n      }, 100, function(result) {\n        assert.strictEqual(result.status, 0);\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.waitUntil() function failure with custom waitForConditionPollInterval', function (done) {\n      let tries = 0;\n      const startTime = new Date().valueOf();\n      let timeDiff;\n      const maxTimeout = 100;\n      const client = this.client.api;\n      let result;\n\n      client.globals.waitForConditionPollInterval = 11;\n\n      this.client.api.waitUntil(function () {\n        assert.deepStrictEqual(this.options, client.options);\n        tries++;\n\n        return false;\n      }, maxTimeout, null, 'custom error message', function(response) {\n        timeDiff = new Date().valueOf() - startTime;\n        result = response;\n      });\n\n      this.client.start(err => {\n        try {\n          assert.ok(err instanceof Error);\n          assert.ok(timeDiff <= maxTimeout + 100, `Expected lower than ${maxTimeout}, but got ${timeDiff}`);\n          assert.strictEqual(result.status, -1);\n          assert.ok(tries > 5);\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/cookies/testCookie.js",
    "content": "const assert = require('assert');\nconst Mocks  = require('../../../../lib/command-mocks.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('get, set and delete cookie', function() {\n  describe('with backwards compat mode', function() {\n    before(function(done) {\n      CommandGlobals.beforeEach.call(this, done, {\n        backwards_compatibility_mode: true\n      });\n    });\n\n    after(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('client.getCookie(<name>)', function(done) {\n      Mocks.cookiesFound({times: 2});\n\n      const api = this.client.api;\n      this.client.api.getCookie('test_cookie', function callback(result) {\n        assert.strictEqual(this, api);\n        assert.strictEqual(result.name, 'test_cookie');\n        assert.strictEqual(result.value, '123456');\n      });\n\n      this.client.api.getCookie('other_cookie', function callback(result) {\n        assert.strictEqual(result, null);\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.cookies.get(<name>)', function(done) {\n      Mocks.cookieFound();\n      Mocks.cookieNotFound();\n\n      const api = this.client.api;\n      this.client.api.cookies.get('test_cookie', function callback(result) {\n        assert.strictEqual(this, api);\n        assert.strictEqual(result.value.name, 'test_cookie');\n        assert.strictEqual(result.value.value, '123456');\n      });\n\n      this.client.api.cookies.get('other_cookie', function callback(result) {\n        assert.strictEqual(result.value, null);\n      });\n\n      this.client.start(done);\n    });\n  });\n\n  describe('without compat mode', function() {\n    before(function(done) {\n      CommandGlobals.beforeEach.call(this, done);\n    });\n\n    after(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('client.getCookie(<name>)', function(done) {\n      Mocks.cookiesFound({times: 2});\n\n      const api = this.client.api;\n      this.client.api.getCookie('test_cookie', function callback(result) {\n        assert.strictEqual(this, api);\n        assert.strictEqual(result.name, 'test_cookie');\n        assert.strictEqual(result.value, '123456');\n      });\n\n      this.client.api.getCookie('other_cookie', function callback(result) {\n        assert.strictEqual(result, null);\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.getCookie(<name>) - empty result', function(done) {\n      Mocks.cookiesNotFound();\n\n      this.client.api.getCookie('other_cookie', function callback(result) {\n        assert.strictEqual(result, null);\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.deleteCookie(<name>)', function(done){\n      Mocks.deleteCookie();\n\n      this.client.api.deleteCookie('other_cookie', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      });\n      this.client.start(done);\n    });\n\n    it('client.setCookie(<name>)', function(done) {\n      Mocks.addCookie();\n\n      this.client.api.setCookie({name: 'other_cookie', value: '123456'}, function callback(result) {\n        assert.strictEqual(result.status, 0);\n      });\n      this.client.start(done);\n    });\n\n    it('client.cookies.get(<name>)', function(done) {\n      Mocks.cookieFound();\n      Mocks.cookieNotFound();\n\n      const api = this.client.api;\n      this.client.api.cookies.get('test_cookie', function callback(result) {\n        assert.strictEqual(this, api);\n        assert.strictEqual(result.value.name, 'test_cookie');\n        assert.strictEqual(result.value.value, '123456');\n      });\n\n      this.client.api.cookies.get('other_cookie', function callback(result) {\n        assert.strictEqual(result.value, null);\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.cookies.get() without any argument', function(done) {\n      this.client.api.cookies.get();\n\n      this.client.start(function(err) {\n        try {\n          assert.ok(err instanceof Error);\n          assert.strictEqual(err.message.includes('First argument passed to .cookies.get() must be a string.'), true);\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n\n    it('client.cookies.delete(<name>)', function(done){\n      Mocks.deleteCookie();\n\n      this.client.api.cookies.delete('other_cookie', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      });\n      this.client.start(done);\n    });\n\n    it('client.cookies.get() without any argument', function(done) {\n      this.client.api.cookies.delete();\n\n      this.client.start(function(err) {\n        try {\n          assert.ok(err instanceof Error);\n          assert.strictEqual(err.message.includes('First argument passed to .cookies.delete() must be a string.'), true);\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n\n    it('client.cookies.set(<name>)', function(done) {\n      Mocks.addCookie();\n\n      this.client.api.cookies.set({name: 'other_cookie', value: '123456'}, function callback(result) {\n        assert.strictEqual(result.status, 0);\n      });\n      this.client.start(done);\n    });\n\n    it('client.cookies.set() without any argument', function(done) {\n      this.client.api.cookies.set();\n\n      this.client.start(function(err) {\n        try {\n          assert.ok(err instanceof Error);\n          assert.strictEqual(err.message.includes('First argument passed to .cookies.set() must be an object; received: undefined (undefined)'), true);\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/cookies/testCookies.js",
    "content": "const assert = require('assert');\nconst Mocks = require('../../../../lib/command-mocks.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('get and delete cookies', function() {\n  describe('with backwards compat mode', function() {\n    before(function(done) {\n      CommandGlobals.beforeEach.call(this, done, {\n        backwards_compatibility_mode: true\n      });\n    });\n\n    after(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('client.getCookies()', function(done) {\n      Mocks.cookiesFound();\n\n      const api = this.client.api;\n      this.client.api.getCookies(function callback(result) {\n        assert.strictEqual(this, api);\n        assert.strictEqual(result.value.length, 1);\n        assert.strictEqual(result.value[0].name, 'test_cookie');\n      });\n\n      this.client.start(done);\n    });\n  });\n\n  describe('without compat mode', function() {\n    before(function(done) {\n      CommandGlobals.beforeEach.call(this, done);\n    });\n\n    after(function(done) {\n      CommandGlobals.afterEach.call(this, done);\n    });\n\n    it('client.getCookies()', function(done) {\n      Mocks.cookiesFound();\n\n      const api = this.client.api;\n      this.client.api.getCookies(function callback(result) {\n        assert.strictEqual(this, api);\n        assert.strictEqual(result.value.length, 1);\n        assert.strictEqual(result.value[0].name, 'test_cookie');\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.getCookies() - empty result', function(done) {\n      Mocks.cookiesNotFound();\n\n      this.client.api.getCookies(function callback(result) {\n        assert.ok(Array.isArray(result.value));\n        assert.strictEqual(result.value.length, 0);\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.deleteCookies(<name>)', function(done){\n      Mocks.deleteCookies();\n\n      this.client.api.deleteCookies(function callback(result) {\n        assert.strictEqual(result.value, null);\n        assert.strictEqual(result.status, 0);\n      });\n      this.client.start(done);\n    });\n\n    it('client.cookies.getAll()', function(done) {\n      Mocks.cookiesFound();\n\n      const api = this.client.api;\n      this.client.api.cookies.getAll(function callback(result) {\n        assert.strictEqual(this, api);\n        assert.strictEqual(result.value.length, 1);\n        assert.strictEqual(result.value[0].name, 'test_cookie');\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.cookies.getAll() - empty result', function(done) {\n      Mocks.cookiesNotFound();\n\n      this.client.api.cookies.getAll(function callback(result) {\n        assert.ok(Array.isArray(result.value));\n        assert.strictEqual(result.value.length, 0);\n      });\n\n      this.client.start(done);\n    });\n\n    it('client.cookies.deleteAll(<name>)', function(done){\n      Mocks.deleteCookies();\n\n      this.client.api.cookies.deleteAll(function callback(result) {\n        assert.strictEqual(result.value, null);\n        assert.strictEqual(result.status, 0);\n      });\n      this.client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/cookies/testCookiesErrors.js",
    "content": "const assert = require('assert');\nconst common = require('../../../../common.js');\nconst SimplifiedReporter = common.require('reporter/simplified.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst Mocks = require('../../../../lib/command-mocks.js');\n\ndescribe('getCookiesErrors', function() {\n  class Reporter extends SimplifiedReporter {\n    constructor(settings) {\n      super(settings);\n\n      this.errors = 0;\n    }\n\n    registerTestError(err) {\n      this.errors++;\n    }\n  }\n\n  describe('with backwards compat mode', function() {\n    beforeEach(function(done) {\n      this.server = MockServer.init();\n      this.server.on('listening', () => done());\n    });\n\n    afterEach(function(done) {\n      this.server.close(() => done());\n    });\n\n    it('client.getCookies() - unhandled error', async function() {\n      const reporter = new Reporter({});\n      const client = await Nightwatch.initClient({\n        report_command_errors: true,\n        backwards_compatibility_mode: true,\n        webdriver: {\n          start_process: false,\n          timeout_options: {\n            retry_attempts: 0\n          }\n        },\n        desiredCapabilities: {\n          name: 'testSuite'\n        },\n        selenium: {\n          port: 10195,\n          start_process: false\n        },\n        output: false,\n        silent: false\n      }, reporter);\n\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/cookie',\n        method: 'GET',\n        statusCode: 500,\n        response: {\n          sessionId: '1352110219202',\n          state: 'unhandled error',\n          value: {\n            message: 'test message'\n          },\n          status: 13\n        }\n      }, true, true);\n\n      client.api.getCookies(function callback(result) {\n        assert.ok(result.error instanceof Error);\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error.message, 'test message');\n        assert.strictEqual(result.error.name, 'WebDriverError');\n      });\n\n      client.api.cookies.getAll(function callback(result) {\n        assert.ok(result.error instanceof Error);\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error.message, 'test message');\n        assert.strictEqual(result.error.name, 'WebDriverError');\n      });\n\n      await new Promise((resolve, reject) => {\n        client.start(err => {\n          if (err) {\n            reject(err);\n          } else {\n            resolve();\n          }\n        });\n      });\n\n      assert.strictEqual(client.reporter.errors, 2);\n    });\n  });\n\n  describe('without compat mode', function() {\n    beforeEach(function(done) {\n      this.server = MockServer.init();\n      this.server.on('listening', () => done());\n    });\n\n    afterEach(function(done) {\n      this.server.close(() => done());\n    });\n\n    it('client.getCookies() - unhandled error', async function() {\n      const reporter = new Reporter({});\n      const client = await Nightwatch.initClient({\n        report_command_errors: true,\n        webdriver: {\n          start_process: false,\n          timeout_options: {\n            retry_attempts: 0\n          }\n        },\n        desiredCapabilities: {\n          name: 'testSuite'\n        },\n        selenium: {\n          port: 10195,\n          start_process: false\n        },\n        output: false,\n        silent: false\n      }, reporter);\n\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/cookie',\n        method: 'GET',\n        statusCode: 500,\n        response: {\n          sessionId: '1352110219202',\n          state: 'unhandled error',\n          value: {\n            message: 'test message'\n          },\n          status: 13\n        }\n      }, true, true);\n\n      client.api.getCookies(function callback(result) {\n        assert.ok(result.error instanceof Error);\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error.message, 'test message');\n        assert.strictEqual(result.error.name, 'WebDriverError');\n      });\n\n      client.api.cookies.getAll(function callback(result) {\n        assert.ok(result.error instanceof Error);\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error.message, 'test message');\n        assert.strictEqual(result.error.name, 'WebDriverError');\n      });\n\n      await new Promise((resolve, reject) => {\n        client.start(err => {\n          if (err) {\n            reject(err);\n          } else {\n            resolve();\n          }\n        });\n      });\n      assert.strictEqual(client.reporter.errors, 2);\n    });\n\n    it('client.getCookies() - socket hang up error', async function() {\n      const reporter = new Reporter({});\n      const client = await Nightwatch.initClient({\n        report_command_errors: false,\n        desiredCapabilities: {\n          name: 'testSuite'\n        },\n        selenium: {\n          port: 10195,\n          start_process: false\n        },\n        webdriver: {\n          start_process: false,\n          timeout_options: {\n            timeout: 50\n          }\n        },\n        output: false,\n        silent: false\n      }, reporter);\n      \n      Mocks.cookiesSocketDelay({times: 6}); // 3 retry attempts per call\n\n      client.api.getCookies(function callback(result) {\n        assert.ok(result.error instanceof Error);\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error.message, 'ECONNRESET socket hang up');\n        assert.strictEqual(result.error.code, 'ECONNRESET');\n      });\n\n      client.api.cookies.getAll(function callback(result) {\n        assert.ok(result.error instanceof Error);\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error.message, 'ECONNRESET socket hang up');\n        assert.strictEqual(result.error.code, 'ECONNRESET');\n      });\n\n      await new Promise((resolve, reject) => {\n        client.start(err => {\n          if (err) {\n            reject(err);\n          } else {\n            resolve();\n          }\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/document/testExecute.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../../lib/globals.js');\nconst utils = require('../../../../lib/utils.js');\n\ndescribe('test executeScript and executeAsyncScript', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('test document.executeScript with string', function () {\n    let opts;\n\n    return Globals.protocolTest({\n      assertion: function (args) {\n        opts = args;\n      },\n      commandName: 'document.executeScript',\n      args: ['<script>function(){return test();}</script>', ['arg1', 'arg2']]\n    }).then((result) => {\n      // result returned by the api command (fakedriver here).\n      assert.strictEqual(result, null);\n\n      assert.deepStrictEqual(opts.command, 'executeScript');\n      assert.deepStrictEqual(opts.script, '<script>function(){return test();}</script>');\n      assert.deepStrictEqual(opts.args, ['arg1', 'arg2']);\n    });\n  });\n\n  it('test document.execute with function', function() {\n    let opts;\n\n    return Globals.protocolTest({\n      assertion: function(args) {\n        opts = args;\n      },\n      commandName: 'document.executeScript',\n      args: [function () {\n        return test();\n      }, ['arg1']]\n    }).then((result) => {\n      assert.strictEqual(opts.command, 'executeScript');\n      assert.strictEqual(opts.script, `var passedArgs = Array.prototype.slice.call(arguments,0); return (function () {${utils.getLineBreak()}        return test();${utils.getLineBreak()}      }).apply(window, passedArgs);`);\n      assert.deepStrictEqual(opts.args, ['arg1']);\n\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('test document.executeScript with no args', function() {\n    let opts;\n\n    return Globals.protocolTest({\n      assertion: function(args) {\n        opts = args;\n      },\n      commandName: 'document.executeScript',\n      args: [function () {\n        return test();\n      }]\n    }).then((result) => {\n      assert.strictEqual(opts.command, 'executeScript');\n      assert.strictEqual(opts.script, `var passedArgs = Array.prototype.slice.call(arguments,0); return (function () {${utils.getLineBreak()}        return test();${utils.getLineBreak()}      }).apply(window, passedArgs);`);\n      assert.deepStrictEqual(opts.args, []);\n\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('test document.executeScript with no script', function() {\n    return Globals.protocolTest({\n      commandName: 'document.executeScript',\n      args: []\n    }).catch(err => {\n      return err;\n    }).then((result) => {\n      assert.ok(result instanceof Error);\n      assert.strictEqual(result.message.includes('First argument passed to .executeScript() must be defined.'), true);\n    });\n  });\n\n  it('test document.executeAsyncScript with string', function() {\n    let opts;\n\n    return Globals.protocolTest({\n      assertion: function(args) {\n        opts = args;\n      },\n      commandName: 'document.executeAsyncScript',\n      args: [function () {\n        return test();\n      }, ['arg1', 'arg2']]\n    }).then((result) => {\n      assert.strictEqual(opts.command, 'executeAsyncScript');\n      assert.strictEqual(opts.script, `var passedArgs = Array.prototype.slice.call(arguments,0); return (function () {${utils.getLineBreak()}        return test();${utils.getLineBreak()}      }).apply(window, passedArgs);`);\n      assert.deepStrictEqual(opts.args, ['arg1', 'arg2']);\n\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('test document.executeAsync with function', function() {\n    let opts;\n\n    return Globals.protocolTest({\n      assertion: function(args) {\n        opts = args;\n      },\n      commandName: 'document.executeAsync',\n      args: ['<script>function(){return test();}</script>', ['arg1']]\n    }).then((result) => {\n      assert.strictEqual(opts.command, 'executeAsyncScript');\n      assert.strictEqual(opts.script, '<script>function(){return test();}</script>');\n      assert.deepStrictEqual(opts.args, ['arg1']);\n\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('test document.executeAsyncScript with no script', function() {\n    return Globals.protocolTest({\n      commandName: 'document.executeAsyncScript',\n      args: []\n    }).catch(err => {\n      return err;\n    }).then((result) => {\n      assert.ok(result instanceof Error);\n      assert.strictEqual(result.message.includes('First argument passed to .executeAsyncScript() must be defined.'), true);\n    });\n  });\n\n  it('testExecuteString', function () {\n    let opts;\n\n    return Globals.protocolTest({\n      assertion: function (args) {\n        opts = args;\n      },\n      commandName: 'executeScript',\n      args: ['<script>function(){return test();}</script>', ['arg1', 'arg2']]\n    }).then((result) => {\n      // result returned by the api command (fakedriver here).\n      assert.strictEqual(result, null);\n\n      assert.deepStrictEqual(opts.command, 'executeScript');\n      assert.deepStrictEqual(opts.script, '<script>function(){return test();}</script>');\n      assert.deepStrictEqual(opts.args, ['arg1', 'arg2']);\n    });\n  });\n\n  it('testExecuteFunction', function() {\n    let opts;\n\n    return Globals.protocolTest({\n      assertion: function(args) {\n        opts = args;\n      },\n      commandName: 'executeScript',\n      args: [function () {\n        return test();\n      }, ['arg1']]\n    }).then((result) => {\n      assert.strictEqual(opts.command, 'executeScript');\n      assert.strictEqual(opts.script, `var passedArgs = Array.prototype.slice.call(arguments,0); return (function () {${utils.getLineBreak()}        return test();${utils.getLineBreak()}      }).apply(window, passedArgs);`);\n      assert.deepStrictEqual(opts.args, ['arg1']);\n\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('testExecuteFunctionNoArgs', function() {\n    let opts;\n\n    return Globals.protocolTest({\n      assertion: function(args) {\n        opts = args;\n      },\n      commandName: 'executeScript',\n      args: [function () {\n        return test();\n      }]\n    }).then((result) => {\n      assert.strictEqual(opts.command, 'executeScript');\n      assert.strictEqual(opts.script, `var passedArgs = Array.prototype.slice.call(arguments,0); return (function () {${utils.getLineBreak()}        return test();${utils.getLineBreak()}      }).apply(window, passedArgs);`);\n      assert.deepStrictEqual(opts.args, []);\n\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('testExecuteAsyncFunction', function() {\n    let opts;\n\n    return Globals.protocolTest({\n      assertion: function(args) {\n        opts = args;\n      },\n      commandName: 'executeAsyncScript',\n      args: [function () {\n        return test();\n      }, ['arg1', 'arg2']]\n    }).then((result) => {\n      assert.strictEqual(opts.command, 'executeAsyncScript');\n      assert.strictEqual(opts.script, `var passedArgs = Array.prototype.slice.call(arguments,0); return (function () {${utils.getLineBreak()}        return test();${utils.getLineBreak()}      }).apply(window, passedArgs);`);\n      assert.deepStrictEqual(opts.args, ['arg1', 'arg2']);\n\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('testExecuteAsyncString', function() {\n    let opts;\n\n    return Globals.protocolTest({\n      assertion: function(args) {\n        opts = args;\n      },\n      commandName: 'executeAsyncScript',\n      args: ['<script>function(){return test();}</script>', ['arg1']]\n    }).then((result) => {\n      assert.strictEqual(opts.command, 'executeAsyncScript');\n      assert.strictEqual(opts.script, '<script>function(){return test();}</script>');\n      assert.deepStrictEqual(opts.args, ['arg1']);\n\n      assert.strictEqual(result, null);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/document/testInjectScript.js",
    "content": "const assert = require('assert');\nconst nock = require('nock');\nconst Nocks = require('../../../../lib/nocks.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\n\ndescribe('document.injectScript()', function() {\n  before(function(done) {\n    Nocks.cleanAll();\n    try {\n      Nocks.enable();\n    } catch (e) {\n      // ignore\n    }\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    Nocks.disable();\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('document.injectScript() with scriptUrl only', async function () {\n    nock('http://localhost:10195')\n      .post('/session/13521-10219-202/execute/sync')\n      .reply(200, function (uri, requestBody) {\n        assert.strictEqual(typeof requestBody.script, 'string');\n        assert.deepStrictEqual(requestBody.args, [\n          'https://some-host.com/some/path'\n        ]);\n\n        return {\n          value: {\n            'element-6066-11e4-a52e-4f735466cecf': '999'\n          }\n        };\n      });\n    \n    let callbackResult;\n    await this.client.api.document.injectScript('https://some-host.com/some/path', function (result) {\n      callbackResult = result;\n    });\n    await this.client.start();\n\n    assert.strictEqual(await callbackResult.value.getId(), '999');\n  });\n\n  it('document.injectScript() with both arguments', async function () {\n    nock('http://localhost:10195')\n      .post('/session/13521-10219-202/execute/sync')\n      .reply(200, function (uri, requestBody) {\n        assert.strictEqual(typeof requestBody.script, 'string');\n        assert.deepStrictEqual(requestBody.args, [\n          'https://some-host.com/some/path',\n          'some-id'\n        ]);\n\n        return {\n          value: {\n            'element-6066-11e4-a52e-4f735466cecf': '998'\n          }\n        };\n      });\n    \n    let callbackResult;\n    await this.client.api.document.injectScript('https://some-host.com/some/path', 'some-id', function (result) {\n      callbackResult = result;\n    });\n    await this.client.start();\n\n    assert.strictEqual(await callbackResult.value.getId(), '998');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/document/testSource.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\n\ndescribe('document.source()', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .document.source()/pageSource()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/source',\n      method: 'GET',\n      response: JSON.stringify({\n        status: 0,\n        value: '<html>Sample HTML</html>'\n      })\n    }, true, true);\n\n    const api = this.client.api;\n    this.client.api.document.source(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, '<html>Sample HTML</html>');\n    });\n    this.client.api.document.pageSource(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, '<html>Sample HTML</html>');\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testCheck.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('.check()', function () {\n  beforeEach(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.check() will click unselected checkbox', function (done) {\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/element/0/click',\n      'response': {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'checkbox'\n      })\n    });\n\n    this.client.api.check('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    }).check('#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.check() will click unselected radio input', function (done) {\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/element/0/click',\n      'response': {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'radio'\n      })\n    });\n\n    this.client.api.check('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    }).check('#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.check() will not click selected checkbox', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: true\n      })\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'checkbox'\n      })\n    });\n\n    this.client.api.check('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    }).check('#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.check() will not click selected radio input', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: true\n      })\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'checkbox'\n      })\n    });\n\n    this.client.api.check('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    }).check('#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testClearValue.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst {Key} = require('selenium-webdriver');\n\ndescribe('clearValue', function() {\n\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => done());\n  });\n\n  after(function(done) {\n    this.server.close(() => done());\n  });\n\n  it('client.clearValue()', function(done) {\n    Nightwatch.initClient({\n      output: false,\n      silent: false\n    })\n      .then(client => {\n        MockServer.addMock({\n          'url': '/wd/hub/session/1352110219202/element/0/clear',\n          'response': {\n            sessionId: '1352110219202',\n            status: 0\n          }\n        });\n\n        client.api.clearValue('#weblogin', function callback(result) {\n          assert.strictEqual(result.status, 0);\n          assert.strictEqual(this, client.api);\n        })\n          .clearValue('css selector', '#weblogin', function callback(result) {\n            assert.strictEqual(result.status, 0);\n          });\n\n        client.start(done);\n      });\n  });\n\n  it('client.clearValue() with invalid locate strategy', function(done) {\n    Nightwatch.initClient({\n      output: false,\n      silent: false\n    })\n      .then(client => {\n        client.api.clearValue('invalid strategy', '#weblogin', function callback(result) {\n          assert.strictEqual(result.status, 0);\n        });\n\n        client.start(function(err) {\n          try {\n            assert.ok(err instanceof Error);\n            assert.ok(err.message.includes('Provided locating strategy \"invalid strategy\" is not supported for .clearValue()'));\n            done();\n          } catch (e) {\n            done(e);\n          }\n        });\n      });\n  });\n\n  it('client.clearValue() with no callback', function(done) {\n    Nightwatch.initClient({\n      output: false,\n      silent: false\n    })\n      .then(client => {\n        MockServer.addMock({\n          'url': '/wd/hub/session/1352110219202/element/0/clear',\n          'response': {\n            sessionId: '1352110219202',\n            status: 0\n          }\n        });\n\n\n        client.api.elements('css selector', 'body', res => {\n          client.api.clearValue('#weblogin');\n        });\n\n        client.start(done);\n      });\n  });\n\n  it('client.clearValue() with webdriver protocol', function(done) {\n    Nightwatch.initClient({\n      selenium: {\n        version2: false,\n        start_process: false,\n        host: null\n      },\n      output: false,\n      silent: false,\n      webdriver: {\n        host: 'localhost',\n        start_process: false\n      }\n    }).then(client => {\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/clear',\n        response: {value: null}\n      }, true);\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/clear',\n        response: {value: null}\n      }, true);\n\n      client.api.clearValue('#webdriver', function(result) {\n        assert.strictEqual(result.value, null);\n      }).clearValue('css selector', '#webdriver', function(result) {\n        assert.strictEqual(result.value, null);\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('client.clearValue() with webdriver protocol - fallback sending backspace keys', function (done) {\n    Nightwatch.initClient({\n      selenium: {\n        version2: false,\n        start_process: false,\n        host: null\n      },\n      output: false,\n      silent: false,\n      webdriver: {\n        host: 'localhost',\n        start_process: false\n      }\n    }).then((client) => {\n      let sendKeysMockCalled = false;\n      let callbackResultValue;\n  \n      MockServer\n        .addMock({\n          url: '/session/13521-10219-202/element/0/clear',\n          response: {value: null}\n        }, true)\n        .addMock({\n          url: '/session/13521-10219-202/element/0/property/value',\n          method: 'GET',\n          response: {value: 'sample'}\n        }, true)\n        .addMock({\n          url: '/session/13521-10219-202/element/0/value',\n          method: 'POST',\n          response: {value: null},\n          onRequest(_, requestData) {\n            assert.strictEqual(requestData.text, Array(6).fill(Key.BACK_SPACE).join(''));\n            sendKeysMockCalled = true;\n          }\n        }, true);\n\n      client.api.clearValue('css selector', '#signupSection', function (result) {\n        callbackResultValue = result.value;\n      });\n  \n      client.start(function (err) {\n        try {\n          assert.strictEqual(err, undefined);\n          assert.strictEqual(callbackResultValue, null);\n          // ensure fallback is working (backspaces are sent to element)\n          assert.strictEqual(sendKeysMockCalled, true);\n          done();\n        } catch (e) {\n          done(e);\n        }\n      });\n    });\n  });\n\n  it('client.clearValue() with webdriver protocol - fallback sending nothing when element cleared correctly', function (done) {\n    Nightwatch.initClient({\n      selenium: {\n        version2: false,\n        start_process: false,\n        host: null\n      },\n      output: false,\n      silent: false,\n      webdriver: {\n        host: 'localhost',\n        start_process: false\n      }\n    }).then((client) => {\n      let sendKeysMockCalled = false;\n      let callbackResultValue;\n  \n      MockServer\n        .addMock({\n          url: '/session/13521-10219-202/element/0/clear',\n          response: {value: null}\n        }, true)\n        .addMock({\n          url: '/session/13521-10219-202/element/0/property/value',\n          method: 'GET',\n          response: {value: ''}\n        }, true)\n        .addMock({\n          url: '/session/13521-10219-202/element/0/value',\n          method: 'POST',\n          response: {value: null},\n          onRequest() {\n            sendKeysMockCalled = true;\n          }\n        }, true);\n\n      client.api.clearValue('css selector', '#signupSection', function (result) {\n        callbackResultValue = result.value;\n      });\n  \n      client.start(function (err) {\n        try {\n          assert.strictEqual(err, undefined);\n          assert.strictEqual(callbackResultValue, null);\n          assert.strictEqual(sendKeysMockCalled, false);\n          done();\n        } catch (e) {\n          done(e);\n        }\n      });\n    });\n  });\n\n  it('client.clearValue() with webdriver protocol - element not found', function(done) {\n    Nightwatch.initClient({\n      selenium: {\n        version2: false,\n        start_process: false,\n        host: null\n      },\n      webdriver: {\n        host: 'localhost',\n        start_process: false\n      },\n      silent: false,\n      output: false,\n      globals: {\n        waitForConditionPollInterval: 5\n      }\n    }).then(client => {\n      let retries = 0;\n      MockServer.addMock({\n        statusCode: 404,\n        url: '/session/13521-10219-202/elements',\n        postdata: {using: 'css selector', value: '#webdriver-notfound'},\n        times: 2,\n        onResponse() {\n          retries++;\n        },\n        response: {\n          value: {\n            error: 'no such element',\n            message: 'Unable to locate element: #webdriver-notfound',\n            stacktrace: 'WebDriverError@chrome://marionette/content/error.js:172:5\\nNoSuchElementError@chrome://marionette/content/error.js:400:5'\n          }\n        }\n      });\n\n      client.api.clearValue({selector: '#webdriver-notfound', timeout: 11}, function(result) {\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(retries, 2);\n        assert.strictEqual(result.value.error, 'An error occurred while running .clearValue() command on <#webdriver-notfound>: Timed out while waiting for element \"#webdriver-notfound\" with \"css selector\" to be present for 11 milliseconds.');\n        assert.strictEqual(result.value.message, 'An error occurred while running .clearValue() command on <#webdriver-notfound>: Timed out while waiting for element \"#webdriver-notfound\" with \"css selector\" to be present for 11 milliseconds.');\n      });\n\n      client.start(done);\n    });\n  });\n});"
  },
  {
    "path": "test/src/api/commands/element/testClick.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('.click()', function() {\n  beforeEach(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.click()', function(done) {\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/element/0/click',\n      'response': {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    });\n    const api = this.client.api;\n    this.client.api.click('#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(this, api);\n    }).click('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.click() with xpath', function(done) {\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/element/0/click',\n      'response': JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0\n      })\n    });\n\n    this.client.api.useXpath()\n      .click('//weblogin', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .click('css selector', '#weblogin', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      });\n\n    this.client.start(done);\n  });\n\n  it('client.click() with webdriver protocol', function(done) {\n    Nightwatch.initW3CClient({\n      silent: false,\n      output: false\n    }).then(client => {\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/click',\n        response: {value: null}\n      }, true);\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/click',\n        response: {value: null}\n      }, true);\n\n      client.api.click('#webdriver', function(result) {\n        assert.strictEqual(result.value, null);\n      }).click('css selector', '#webdriver', function(result) {\n        assert.strictEqual(result.value, null);\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('client.click() - element not interactable error - failed', function(done) {\n    Nightwatch.initW3CClient({\n      output: false,\n      silent: false\n    }).then(client => {\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/click',\n        statusCode: 400,\n        response: {\n          value: {\n            error: 'element not interactable',\n            message: 'Element <h1> could not be scrolled into view',\n            stacktrace: ''\n          }\n        }\n      }, null, true);\n\n      let response;\n      client.api.click({\n        retryInterval: 50,\n        timeout: 100,\n        selector: '#webdriver'\n      }, function(result) {\n        response = result;\n      });\n\n      client.start(function() {\n        try {\n          assert.strictEqual(response.status, -1);\n          assert.strictEqual(response.value.error, 'An error occurred while running .click() command on <#webdriver>: Element <h1> could not be scrolled into view');\n\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n  });\n\n  it('client.click() - element not interactable error - success', function(done) {\n    Nightwatch.initW3CClient({\n      output: false,\n      silent: false\n    }).then(client => {\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/click',\n        statusCode: 400,\n        response: {\n          value: {\n            error: 'element not interactable',\n            message: 'Element <h1> could not be scrolled into view',\n            stacktrace: ''\n          }\n        }\n      }, true);\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/click',\n        response: {value: null}\n      }, true);\n\n      let response;\n      client.api.click({\n        retryInterval: 50,\n        selector: '#webdriver'\n      }, function(result) {\n        response = result;\n      });\n\n      client.start(function() {\n        try {\n          assert.strictEqual(response.value, null);\n\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n    });\n  });\n\n  it('client.click() - stale element reference error', function(done) {\n    Nightwatch.initW3CClient({\n      output: false,\n      silent: false\n    }).then(client => {\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/click',\n        statusCode: 404,\n        response: {\n          value: {\n            error: 'stale element reference',\n            message: 'stale element reference',\n            stacktrace: ''\n          }\n        }\n      }, true);\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/click',\n        response: {\n          value: null\n        }\n      }, true);\n\n      client.api.click('#webdriver', function(result) {\n        assert.strictEqual(result.value, null);\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('client.click() - for native app', function(done) {\n    Nightwatch.initW3CClient({\n      output: false,\n      silent: false,\n      selenium: {\n        start_process: false,\n        use_appium: true,\n        port: 10195,\n        host: 'localhost'\n      },\n      desiredCapabilities: {\n        'appium:automationName': 'XCUITest',\n        browserName: null,\n        'appium:appPackage': 'org.wikimedia.wikipedia',\n        platformName: 'iOS',\n        'appium:deviceName': 'iPhone 13',\n        'appium:platformVersion': '15.5'\n      }\n    }).then(client => {\n      MockServer.addMock({\n        'url': '/wd/hub/session/13521-10219-202/elements',\n        'postdata': {'using':'css selector','value':'#webdriver'},\n        'response': {\n          value: [{\n            'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n          }],\n          status: 0\n        }\n      });\n\n      MockServer.addMock({\n        url: '/wd/hub/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/click',\n        response: {value: null}\n      }, true);\n\n      assert.strictEqual(client.api.browserName, null);\n      assert.strictEqual(client.api.platformName, 'iOS');\n\n      client.api.click('#webdriver', function(result) {\n        assert.strictEqual(result.value, null);\n      });\n\n      client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testClickAndHold.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\n\ndescribe('.clickAndHold()', function() {\n  beforeEach(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.clickAndHold()', function(done) {\n    const api = this.client.api;\n    let clickAndHoldArgs;\n    \n    this.client.transport.Actions.session.pressAndHold = function(args) {\n      clickAndHoldArgs = args;\n      \n      return Promise.resolve({\n        status: 0,\n        value:null\n      });\n    }\n    \n    this.client.api.clickAndHold('#weblogin', function callback(result) {\n      assert.deepStrictEqual(clickAndHoldArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b'])\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(this, api);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.clickAndHold() with xpath', function(done) {\n\n    let clickAndHoldArgs;\n    this.client.transport.Actions.session.pressAndHold = function(args) {\n      clickAndHoldArgs = args;\n\n      return Promise.resolve({\n        status:0,\n        value: null\n      })\n    }\n\n    this.client.api.useXpath()\n      .clickAndHold('//weblogin', function callback(result) {\n        assert.deepStrictEqual(clickAndHoldArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b'])\n        assert.strictEqual(result.status, 0);\n      })\n     \n\n    this.client.start(done);\n  });\n\n\n  it('client.clickAndHold() - element not interactable error - failed', function(done) {\n    \n    let clickAndHoldArgs;\n    this.client.transport.Actions.session.pressAndHold = function(args) {\n      clickAndHoldArgs = args;\n      return Promise.resolve({\n        status: -1,\n        value: null,\n        error: new Error('Element could not be scrolled into view')\n      });\n    }\n\n    this.client.api.clickAndHold({\n      retryInterval: 50,\n      timeout: 100,\n      selector: '#weblogin'\n    }, function(result) {\n      assert.deepStrictEqual(clickAndHoldArgs.args,['5cc459b8-36a8-3042-8b4a-258883ea642b'])\n      assert.strictEqual(result.status, -1);\n      assert.strictEqual(result.value.error,'An error occurred while running .clickAndHold() command on <#weblogin>: Element could not be scrolled into view')\n    });\n\n    this.client.start(done);\n  });\n\n\n\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testClickMobile.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('.click()', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => done());\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.click() with xpath on iOS', function(done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'safari',\n            platformName: 'iOS',\n            'safari:useSimulator': true,\n            'safari:platformVersion': '15.6.1'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      postdata: {\n        'script': 'arguments[0].click();',\n        'args': [{'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b', 'ELEMENT': '5cc459b8-36a8-3042-8b4a-258883ea642b'}]\n      },\n      response: JSON.stringify({\n        sessionId: '13521-10219-202',\n        status: 0\n      })\n    });\n\n    Nightwatch.initW3CClient({\n      silent: false,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'safari',\n        platformName: 'iOS',\n        'safari:useSimulator': true\n      }\n    }).then((client) => {\n      client.api.click('css selector', '#weblogin', function(result) {\n        assert.strictEqual(result.status, 0);\n      });\n  \n      client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testDoubleClick.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\n\ndescribe('.doubleClick()', function() {\n  beforeEach(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.doubleClick()', function(done) {\n   \n    const api = this.client.api;\n    let doubleClickArgs;\n    this.client.transport.Actions.session.doubleClick = function(args) {\n      doubleClickArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n    \n    this.client.api.doubleClick('#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n      assert.deepStrictEqual(doubleClickArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b']);\n      assert.strictEqual(this, api);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.doubleClick() with xpath', function(done) {\n\n    let doubleClickArgs;\n    this.client.transport.Actions.session.doubleClick = function(args) {\n      doubleClickArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    this.client.api.useXpath()\n      .doubleClick('//weblogin', function callback(result) {\n        assert.deepStrictEqual(doubleClickArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b']);\n        assert.strictEqual(result.status, 0);\n      });\n    this.client.start(done);\n  });\n \n  it('client.doubleClick() - element not interactable error - failed', function(done) {\n    \n    let doubleClickArgs;\n    this.client.transport.Actions.session.doubleClick = function(args) {\n      doubleClickArgs = args;\n\n      return Promise.resolve({\n        status: -1,\n        value: null,\n        error: new Error('Element could not be scrolled into view')\n      });\n    };\n\n    this.client.api.doubleClick({\n      retryInterval: 50,\n      timeout: 100,\n      selector: '#weblogin'\n    }, function(result) {\n      assert.deepStrictEqual(doubleClickArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b']);\n      assert.strictEqual(result.status, -1);\n      assert.strictEqual(result.value.error, 'An error occurred while running .doubleClick() command on <#weblogin>: Element could not be scrolled into view');\n    });\n\n    this.client.start(done);\n  });\n\n});"
  },
  {
    "path": "test/src/api/commands/element/testDragAndDrop.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('moveToElement', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.dragAndDrop()', function(done) {\n    let dragArgs ;\n    this.client.transport.Actions.session.dragElement = function({args, sessionId}) {\n      dragArgs = args;\n\n      return Promise.resolve({\n        status: 0\n      });\n    };\n\n    this.client.api.dragAndDrop('css selector', '#weblogin', {x: 10, y: 10}, function(result) {\n      assert.deepStrictEqual(dragArgs, ['0', {x: 10, y: 10}]);\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.dragAndDrop() with destination as a webelement ', function(done) {\n    let dragArgs ;\n    this.client.transport.Actions.session.dragElement = function({args, sessionId}) {\n      dragArgs = args;\n\n      return Promise.resolve({\n        status: 0\n      });\n    };\n\n    this.client.api.dragAndDrop('css selector', '#weblogin', '0', function(result) {\n      assert.deepStrictEqual(dragArgs, ['0', '0']);\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetAccessibleName.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getAccessibleName', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getAccessibleName()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/computedlabel',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'search input'\n      })\n    });\n\n    this.client.api\n      .getAccessibleName('#weblogin', function callback(result) {\n        assert.strictEqual(result.value, 'search input');\n      })\n      .getAccessibleName('css selector', '#weblogin', function callback(result) {\n        assert.strictEqual(result.value, 'search input');\n      })\n      .getAccessibleName('css selector', {selector: '#weblogin', timeout: 100}, function callback(result) {\n        assert.strictEqual(result.value, 'search input');\n      })\n      .getAccessibleName({selector: '#weblogin', timeout: 100}, function callback(result) {\n        assert.strictEqual(result.value, 'search input');\n      });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetAriaRole.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getAriaRole', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getAriaRole()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/computedrole',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'combobox'\n      })\n    });\n\n    this.client.api\n      .getAriaRole('#weblogin', function callback(result) {\n        assert.strictEqual(result.value, 'combobox');\n      })\n      .getAriaRole('css selector', '#weblogin', function callback(result) {\n        assert.strictEqual(result.value, 'combobox');\n      })\n      .getAriaRole(\n        'css selector',\n        {\n          selector: '#weblogin',\n          timeout: 100\n        },\n        function callback(result) {\n          assert.strictEqual(result.value, 'combobox');\n        }\n      )\n      .getAriaRole(\n        {\n          selector: '#weblogin',\n          timeout: 100\n        },\n        function callback(result) {\n          assert.strictEqual(result.value, 'combobox');\n        }\n      );\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetAttribute.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getAttribute', function() {\n\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getAttribute()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'test_class'\n      })\n    }, true, true);\n\n    this.client.api.getAttribute('#weblogin', 'class', function callback(result) {\n      assert.strictEqual(result.value, 'test_class');\n    }).getAttribute('css selector', '#weblogin', 'class', function callback(result) {\n      assert.strictEqual(result.value, 'test_class');\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetAttributeW3c.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\n\ndescribe('getAttribute', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getAttribute()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'test_class'\n      })\n    }, true, true);\n\n    this.client.api.getAttribute('#weblogin', 'class', function callback(result) {\n      assert.strictEqual(result.value, 'test_class');\n    }).getAttribute('css selector', '#weblogin', 'class', function callback(result) {\n      assert.strictEqual(result.value, 'test_class');\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.getAttribute() -- appium', function(done) {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/elements',\n        postdata: {\n          using: 'id',\n          value: 'com.app:id/weblogin'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '999'}]\n        })\n      }, true, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/999/attribute/class',\n        method: 'GET',\n        response: JSON.stringify({\n          value: 'test_class'\n        })\n      }, true, true);\n\n    // Make appium client\n    this.client.api.options.selenium.use_appium = true;\n\n    this.client.api.getAttribute('id', 'com.app:id/weblogin', 'class', function callback(result) {\n      assert.strictEqual(result.value, 'test_class');\n    }).getAttribute({selector: 'com.app:id/weblogin', locateStrategy: 'id'}, 'class', function callback(result) {\n      assert.strictEqual(result.value, 'test_class');\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetCssProperty.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getCssProperty', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getCssProperty()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/css/display',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'block'\n      })\n    });\n\n    this.client.api.getCssProperty('#weblogin', 'display', function callback(result) {\n      assert.strictEqual(result.value, 'block');\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetElementProperty.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getElementProperty', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getElementProperty()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/property/display',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'block'\n      })\n    });\n\n    this.client.api.getElementProperty('#weblogin', 'display', function callback(result) {\n      assert.strictEqual(result.value, 'block');\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetElementRect.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getElementRect', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getElementRect()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: {\n          x: 1,\n          y: 1,\n          width: 100,\n          height: 100\n        }\n      })\n    });\n\n    this.client.api\n      .getElementRect('#weblogin', function callback(result) {\n        assert.deepStrictEqual(result, {\n          status: 0,\n          value: {\n            x: 1,\n            y: 1,\n            width: 100,\n            height: 100\n          }\n        });\n      })\n      .getElementRect('css selector', '#weblogin', function callback(result) {\n        assert.deepStrictEqual(result, {\n          status: 0,\n          value: {\n            x: 1,\n            y: 1,\n            width: 100,\n            height: 100\n          }\n        });\n      });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetElementSize.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getElementSize', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done, {\n      output: false\n    });\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getElementSize()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: {\n          width: 10,\n          height: 20,\n          x: 1,\n          y: 0\n        }\n      })\n    }, null, true);\n\n    this.client.api.getElementSize('#weblogin', function callback(result) {\n      assert.deepStrictEqual(result, {\n        status: 0,\n        value: {\n          x: 1,\n          y: 0,\n          width: 10,\n          height: 20\n        }\n      });\n    }).getElementSize('css selector', '#weblogin', function callback(result) {\n      assert.deepStrictEqual(result, {\n        status: 0,\n        value: {\n          x: 1,\n          y: 0,\n          width: 10,\n          height: 20\n        }\n      });\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.getElementSize() with webdriver protocol', function (done) {\n    Nightwatch.initW3CClient({\n\n    }).then(client => {\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/rect',\n        method: 'GET',\n        response: {\n          value: {\n            x: 341.5,\n            y: 340.95001220703125,\n            width: 683,\n            height: 60\n          }\n        }\n      }, true);\n\n      client.api.getElementSize('#webdriver', function (result) {\n        assert.deepStrictEqual(result, {\n          status: 0,\n          value: {\n            x: 341.5,\n            y: 340.95001220703125,\n            width: 683,\n            height: 60\n          }\n        });\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('client.getElementSize() with webdriver protocol - element not found', function (done) {\n    Nightwatch.initClient({\n      selenium: {\n        version2: false,\n        start_process: false,\n        host: null\n      },\n      webdriver: {\n        host: 'localhost',\n        start_process: false\n      },\n      silent: false,\n      output: false,\n      globals: {\n        waitForConditionPollInterval: 10\n      }\n    }).then(client => {\n      MockServer.addMock({\n        statusCode: 404,\n        url: '/session/13521-10219-202/elements',\n        postdata: {using: 'css selector', value: '#webdriver-notfound'},\n        response: {\n          value: {\n            error: 'no such element',\n            message: 'Unable to locate element: #webdriver-notfound',\n            stacktrace: 'WebDriverError@chrome://marionette/content/error.js:172:5\\nNoSuchElementError@chrome://marionette/content/error.js:400:5'\n          }\n        },\n        times: 2\n      });\n\n      client.api.getElementSize({selector: '#webdriver-notfound', timeout: 10}, function (result) {\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.value.error, 'An error occurred while running .getElementSize() command on <#webdriver-notfound>: Timed out while waiting for element \"#webdriver-notfound\" with \"css selector\" to be present for 10 milliseconds.');\n        assert.strictEqual(result.value.message, 'An error occurred while running .getElementSize() command on <#webdriver-notfound>: Timed out while waiting for element \"#webdriver-notfound\" with \"css selector\" to be present for 10 milliseconds.');\n      });\n\n      client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetFirstElementChild.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\n\ndescribe('browser.getFirstElementChild', function () {\n\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('.getFirstElementChild', function (done) {\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: {\n        value: {\n          'ELEMENT': '1'\n        }\n      }\n    }, true);\n\n    this.client.api.getFirstElementChild('#weblogin', function callback(result) {\n      assert.strictEqual(result.value.getId(), '1');\n    });\n    this.client.start(done);\n  });\n\n\n  it('.getFirstElementChild - no such element', function (done) {\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      method: 'POST',\n      postdata: {\n        using: 'css selector',\n        value: '#badDriver'\n      },\n\n      response: {\n        status: 0,\n        sessionId: '1352110219202',\n        value: [{\n          ELEMENT: '2'\n        }]\n      }\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n\n      response: {\n        status: 0,\n        value: null\n      }\n    });\n\n    this.client.api.getFirstElementChild('#badDriver', function callback(result) {\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n\n\n  it('.getFirstElementChild - webdriver protcol', function (done) {\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: {\n            'element-6066-11e4-a52e-4f735466cecf': 'f54dc0ef-c84f-424a-bad0-16fef6595a70'\n          }\n        }\n      }, true);\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: {\n            'element-6066-11e4-a52e-4f735466cecf': 'f54dc0ef-c84f-424a-bad0-16fef6595a70'\n          }\n        }\n      }, true);\n\n      client.api.getFirstElementChild('#webdriver', function (result) {\n        assert.ok(result.value);\n        assert.strictEqual(result.value.getId(), 'f54dc0ef-c84f-424a-bad0-16fef6595a70');\n      }).getFirstElementChild('#webdriver', function callback(result) {\n        assert.ok(result.value);\n        assert.strictEqual(result.value.getId(), 'f54dc0ef-c84f-424a-bad0-16fef6595a70');\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('.getFirstElementChild - webdriver protcol no such element', function (done) {\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: null\n        }\n      });\n\n      client.api.getFirstElementChild('#webdriver', function (result) {\n        assert.strictEqual(result.value, null);\n      });\n\n      client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetLastElementChild.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\n\ndescribe('browser.getLastElementChild', function () {\n\n\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n\n\n  it('.getLastElementChild', function (done) {\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: {\n        value: {\n          'ELEMENT': '1'\n        }\n      }\n    }, true);\n\n    this.client.api.getLastElementChild('#weblogin', function callback(result) {\n      assert.ok(result.value);\n      assert.strictEqual(result.value.getId(), '1');\n    });\n    this.client.start(done);\n  });\n\n\n  it('.getLastElementChild - no such element', function (done) {\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      method: 'POST',\n      postdata: {\n        using: 'css selector',\n        value: '#badDriver'\n      },\n\n      response: {\n        status: 0,\n        sessionId: '1352110219202',\n        value: [{\n          ELEMENT: '2'\n        }]\n      }\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n\n\n      response: {\n        status: 0,\n        value: null\n      }\n    });\n\n    this.client.api.getLastElementChild('#badDriver', function callback(result) {\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n\n\n  it('.getLastElementChild - webdriver protcol', function (done) {\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: {\n            'element-6066-11e4-a52e-4f735466cecf': 'f54dc0ef-c84f-424a-bad0-16fef6595a70'\n          }\n        }\n      }, true);\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: {\n            'element-6066-11e4-a52e-4f735466cecf': 'f54dc0ef-c84f-424a-bad0-16fef6595a70'\n          }\n        }\n      }, true);\n\n      client.api.getLastElementChild('#webdriver', function (result) {\n        assert.ok(result.value);\n        assert.strictEqual(result.value.getId(), 'f54dc0ef-c84f-424a-bad0-16fef6595a70');\n      }).getLastElementChild('#webdriver', function callback(result) {\n        assert.ok(result.value);\n        assert.strictEqual(result.value.getId(), 'f54dc0ef-c84f-424a-bad0-16fef6595a70');\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('.getLastElementChild - webdriver protcol no such element', function (done) {\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: null\n        }\n      });\n\n      client.api.getLastElementChild('#webdriver', function (result) {\n        assert.strictEqual(result.value, null);\n      });\n\n      client.start(done);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetLocation.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getLocation', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getLocation()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/rect',\n      method: 'GET',\n      response: {\n        sessionId: '1352110219202',\n        status: 0,\n        value: {\n          width: 10,\n          height: 20,\n          x: 1,\n          y: 0\n        }\n      }\n    });\n\n    this.client.api.getLocation('css selector', '#weblogin', function callback(result) {\n      assert.deepStrictEqual(result, {status: 0, value: {x: 1, y: 0, width: 10, height: 20}});\n    }).getLocation('#weblogin', function callback(result) {\n      assert.deepStrictEqual(result, {status: 0, value: {x: 1, y: 0, width: 10, height: 20}});\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.getLocation() with webdriver protocol', function (done) {\n    Nightwatch.initW3CClient({\n    }).then(client => {\n      MockServer.addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/rect',\n        method: 'GET',\n        response: {\n          value: {\n            x: 341.5,\n            y: 340.95001220703125,\n            width: 683,\n            height: 60\n          }\n        }\n      }, true);\n\n      client.api.getLocation('#webdriver', function (result) {\n        assert.deepStrictEqual(result, {\n          status: 0,\n          value: {\n            x: 341.5,\n            y: 340.95001220703125,\n            width: 683,\n            height: 60\n          }\n        });\n      });\n\n      client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetLocationInView.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getLocationInView', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getLocationInView()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/location_in_view',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: {\n          x: 1,\n          y: 0\n        }\n      })\n    });\n\n    this.client.api.getLocationInView('css selector', '#weblogin', function callback(result) {\n      assert.deepStrictEqual(result.value, {x: 1, y: 0});\n    }).getLocationInView('#weblogin', function callback(result) {\n      assert.deepStrictEqual(result.value, {x: 1, y: 0});\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetNextSibling.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\n\ndescribe('browser.getNextSibling', function () {\n\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('.getNextSibling', function (done) {\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: {\n        value: {\n          'ELEMENT': '1'\n        }\n      }\n    }, true);\n\n    this.client.api.getNextSibling('#weblogin', function callback(result) {\n      assert.ok(result.value);\n      assert.strictEqual(result.value.getId(), '1');\n    });\n    this.client.start(done);\n  });\n\n\n  it('.getNextSibling - no such element', function (done) {\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      method: 'POST',\n      postdata: {\n        using: 'css selector',\n        value: '#badDriver'\n      },\n\n      response: {\n        status: 0,\n        sessionId: '1352110219202',\n        value: [{\n          ELEMENT: '2'\n        }]\n      }\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: {\n        status: 0,\n        value: null\n      }\n    });\n\n    this.client.api.getNextSibling('#badDriver', function callback(result) {\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('.getNextSibling - webdriver protcol', function (done) {\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: {\n            'element-6066-11e4-a52e-4f735466cecf': 'f54dc0ef-c84f-424a-bad0-16fef6595a70'\n          }\n        }\n      }, true);\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: {\n            'element-6066-11e4-a52e-4f735466cecf': 'f54dc0ef-c84f-424a-bad0-16fef6595a70'\n          }\n        }\n      }, true);\n\n      client.api.getNextSibling('#webdriver', function (result) {\n        assert.ok(result.value);\n        assert.strictEqual(result.value.getId(), 'f54dc0ef-c84f-424a-bad0-16fef6595a70');\n      }).getNextSibling('#webdriver', function callback(result) {\n        assert.ok(result.value);\n        assert.strictEqual(result.value.getId(), 'f54dc0ef-c84f-424a-bad0-16fef6595a70');\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('.getNextSibling - webdriver protcol no such element', function (done) {\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: null\n        }\n      });\n\n      client.api.getNextSibling('#webdriver', function (result) {\n        assert.strictEqual(result.value, null);\n      });\n\n      client.start(done);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetPreviousSibling.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\n\ndescribe('browser.getPreviousSibling', function () {\n\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n\n\n  it('.getPreviousSibling', function (done) {\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n\n      response: {\n        value: {\n          'ELEMENT': '1'\n        }\n      }\n    }, true);\n\n    this.client.api.getPreviousSibling('#weblogin', function callback(result) {\n      assert.ok(result.value);\n      assert.strictEqual(result.value.getId(), '1');\n    });\n    this.client.start(done);\n  });\n\n\n  it('.getPreviousSibling - no such element', function (done) {\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      method: 'POST',\n      postdata: {\n        using: 'css selector',\n        value: '#badDriver'\n      },\n\n      response: {\n        status: 0,\n        sessionId: '1352110219202',\n        value: [{\n          ELEMENT: '2'\n        }]\n      }\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: {\n        status: 0,\n        value: null\n      }\n    });\n\n    this.client.api.getPreviousSibling('#badDriver', function callback(result) {\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n\n\n  it('.getPreviousSibling - webdriver protcol', function (done) {\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: {\n            'element-6066-11e4-a52e-4f735466cecf': 'f54dc0ef-c84f-424a-bad0-16fef6595a70'\n          }\n        }\n      }, true);\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: {\n            'element-6066-11e4-a52e-4f735466cecf': 'f54dc0ef-c84f-424a-bad0-16fef6595a70'\n          }\n        }\n      }, true);\n\n      client.api.getPreviousSibling('#webdriver', function (result) {\n        assert.ok(result.value);\n        assert.strictEqual(result.value.getId(), 'f54dc0ef-c84f-424a-bad0-16fef6595a70');\n      }).getPreviousSibling('#webdriver', function callback(result) {\n        assert.ok(result.value);\n        assert.strictEqual(result.value.getId(), 'f54dc0ef-c84f-424a-bad0-16fef6595a70');\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('.getPreviousSibling - webdriver protcol no such element', function (done) {\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: null\n        }\n      });\n\n      client.api.getPreviousSibling('#webdriver', function (result) {\n        assert.strictEqual(result.value, null);\n      });\n\n      client.start(done);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetTagName.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getTagName', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n\n  it('client.getTagName()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/name',\n      method: 'GET',\n      response: {\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'div'\n      }\n    });\n\n    this.client.api.getTagName('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.value, 'div');\n    }).getTagName('#weblogin', function callback(result) {\n      assert.strictEqual(result.value, 'div');\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetText.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getText', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getText()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/text',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'sample text'\n      })\n    });\n\n    this.client.api.getText('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.value, 'sample text');\n    }).getText('#weblogin', function callback(result) {\n      assert.strictEqual(result.value, 'sample text');\n    });\n\n    this.client.start(done);\n  });\n});"
  },
  {
    "path": "test/src/api/commands/element/testGetTitle.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getTitle', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n  it('client.getTitle()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/title',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'sample Title'\n      })\n    });\n\n    this.client.api.getTitle(function callback(result) {\n      assert.strictEqual(result, 'sample Title');\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testGetValue.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getValue', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getValue()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/property/value',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'test value'\n      })\n    });\n\n    this.client.api.getValue('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.value, 'test value');\n    }).getValue('#weblogin', function callback(result) {\n      assert.strictEqual(result.value, 'test value');\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testHasDescendants.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\n\ndescribe('browser.hasDescendants', function () {\n\n\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('.hasDescendants', function (done) {\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: {\n        value: 1\n      }\n    }, true);\n\n    this.client.api.hasDescendants('#weblogin', function callback(result) {\n      assert.ok(result.value);\n      assert.strictEqual(result.value, true);\n    });\n    this.client.start(done);\n  });\n\n\n  it('.hasDescendants - no child element', function (done) {\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      method: 'POST',\n      postdata: {\n        using: 'css selector',\n        value: '#badDriver'\n      },\n\n      response: {\n        status: 0,\n        sessionId: '1352110219202',\n        value: [{\n          ELEMENT: '2'\n        }]\n      }\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: {\n        status: 0,\n        value: 0\n      }\n    });\n\n    this.client.api.hasDescendants('#badDriver', function callback(result) {\n      assert.strictEqual(result.value, false);\n    });\n\n    this.client.start(done);\n  });\n\n\n\n  it('.hasDescendants - webdriver protcol', function (done) {\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: 4\n        }\n      }, true);\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: 2\n        }\n      }, true);\n\n      client.api.hasDescendants('#webdriver', function (result) {\n        assert.strictEqual(result.value, true);\n      }).hasDescendants('#webdriver', function callback(result) {\n        assert.strictEqual(result.value, true);\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('.hasDescendants - webdriver protcol no such element', function (done) {\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n\n      MockServer.addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        response: {\n          value: 0\n        }\n      });\n\n      client.api.hasDescendants('#webdriver', function (result) {\n        assert.strictEqual(result.value, false);\n      });\n\n      client.start(done);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testIsEnabled.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('isEnabled', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function() {\n    MockServer.removeMock({\n      url: '/wd/hub/session/1352110219202/element/0/enabled',\n      method: 'GET'\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.isEnabled()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/enabled',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: true\n      })\n    });\n\n    this.client.api.isEnabled('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.value, true);\n    }).isEnabled('#weblogin', function callback(result) {\n      assert.strictEqual(result.value, true);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testIsPresent.js",
    "content": "const assert =  require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands');\nconst MockServer = require('../../../../lib/mockserver');\nconst Nightwatch = require('../../../../lib/nightwatch');\n\n\ndescribe('browser.isPresent', function(){\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n    \n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('isPresent - element found successfully', function(done){\n    this.client.api.isPresent('#weblogin', function(result){\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, true);\n    });\n\n    this.client.start(done);\n  });\n\n  it('.isPresent - no element found', function(done) { \n    this.client.api.isPresent({\n      locateStrategy: 'css selector',\n      timeout: 150,\n      selector: '#badElement'\n    }, function(result) {\n      assert.strictEqual(result.value, false);\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n\n  it('.isPresent - webdriver protocol', function(done){\n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    })\n      .then(client=>{\n        client.api.isPresent('#webdriver', function(result){\n          assert.strictEqual(result.value, true);\n      \n        }).isPresent('#weblogin', function(result){\n          assert.strictEqual(result.value, true);\n        });\n          \n        client.start(done);\n      });\n\n  \n  });\n\n  it('.isPresent - webdriver protocol no such element', function(done){\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '#badElement'\n      },\n      response: {\n        value: []\n      }\n    });\n      \n    Nightwatch.initW3CClient({\n      silent: true,\n      output: false\n    }).then(client => {\n      client.api.isPresent({\n        selector: '#badElement',\n        timeout: 150\n      }, function(result){\n        assert.strictEqual(result.value, false);\n        \n      });\n            \n      client.start(done);\n    });\n  });\n});"
  },
  {
    "path": "test/src/api/commands/element/testIsSelected.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('isSelected', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function() {\n    MockServer.removeMock({\n      url: '/wd/hub/session/1352110219202/element/0/selected',\n      method: 'GET'\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.isEnabled()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: true\n      })\n    });\n\n    this.client.api.isSelected('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.value, true);\n    }).isSelected('#weblogin', function callback(result) {\n      assert.strictEqual(result.value, true);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testIsVisible.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('isVisible', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function () {\n    MockServer.removeMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST'\n    });\n    MockServer.removeMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      method: 'POST'\n    });\n    MockServer.removeMock({\n      url: '/wd/hub/session/1352110219202/element/999/displayed',\n      method: 'GET'\n    });\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.isVisible() [visible]', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: true\n      })\n    });\n\n    this.client.api.isVisible('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.value, true);\n    }).isVisible('#weblogin', function callback(result) {\n      assert.strictEqual(result.value, true);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.isVisible() [not visible]', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    });\n\n    this.client.api.isVisible('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.value, false);\n    }).isVisible('#weblogin', function callback(result) {\n      assert.strictEqual(result.value, false);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.isVisible() [visible] -- appium', function (done) {\n    MockServer\n      .addMock({\n        url: '/wd/hub/session/1352110219202/elements',\n        postdata: {\n          using: 'id',\n          value: 'com.app:id/weblogin'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '999'}]\n        })\n      })\n      .addMock({\n        url: '/wd/hub/session/1352110219202/element/999/displayed',\n        method: 'GET',\n        response: JSON.stringify({\n          value: true\n        })\n      });\n\n    // Make appium client\n    this.client.api.options.selenium.use_appium = true;\n\n    this.client.api.isVisible('id', 'com.app:id/weblogin', function callback(result) {\n      assert.strictEqual(result.value, true);\n    }).isVisible({selector: 'com.app:id/weblogin', locateStrategy: 'id'}, function callback(result) {\n      assert.strictEqual(result.value, true);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.isVisible() [not visible] -- appium', function (done) {\n    MockServer\n      .addMock({\n        url: '/wd/hub/session/1352110219202/elements',\n        postdata: {\n          using: 'id',\n          value: 'com.app:id/weblogin'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '999'}]\n        })\n      })\n      .addMock({\n        url: '/wd/hub/session/1352110219202/element/999/displayed',\n        method: 'GET',\n        response: JSON.stringify({\n          value: false\n        })\n      });\n\n    // Make appium client\n    this.client.api.options.selenium.use_appium = true;\n\n    assert.strictEqual(this.client.api.isAppiumClient(), true);\n\n    this.client.api.isVisible('id', 'com.app:id/weblogin', function callback(result) {\n      assert.strictEqual(result.value, false);\n    }).isVisible({selector: 'com.app:id/weblogin', locateStrategy: 'id'}, function callback(result) {\n      assert.strictEqual(result.value, false);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testMoveToElement.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('moveToElement', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.moveToElement()', function(done) {\n    let moveToArgs;\n    this.client.transport.Actions.session.moveTo = function({args, sessionId}) {\n      moveToArgs = args;\n\n      return Promise.resolve({\n        status: 0\n      });\n    };\n\n    this.client.api.moveToElement('css selector', '#weblogin', null, null, function(result) {\n      assert.deepStrictEqual(moveToArgs, ['0', null, null]);\n      assert.strictEqual(result.status, 0);\n    }).moveToElement('#weblogin', null, null, function(result) {\n      assert.deepStrictEqual(moveToArgs, ['0', null, null]);\n      assert.strictEqual(result.status, 0);\n    }).moveTo('0', null, null, function(result) {\n      assert.deepStrictEqual(moveToArgs, ['0', 0, 0]);\n      assert.strictEqual(result.status, 0);\n    }).moveToElement('#weblogin', 1, 1, function(result) {\n      assert.deepStrictEqual(moveToArgs, ['0', 1, 1]);\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testRightClick.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\n\ndescribe('.rightClick()', function() {\n  beforeEach(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.rightClick()', function(done) {\n    const api = this.client.api;\n    let rightClickArgs;\n    \n    this.client.transport.Actions.session.contextClick = function (args) {\n      rightClickArgs = args;\n      \n      return Promise.resolve({\n        status:0,\n        value: null\n      })\n    }\n\n    this.client.api.rightClick('#weblogin', function callback(result) {\n      assert.deepStrictEqual(rightClickArgs.args,['5cc459b8-36a8-3042-8b4a-258883ea642b'])\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(this, api);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.rightClick() with xpath', function(done) {\n    let rightClickArgs;\n    this.client.transport.Actions.session.contextClick = function (args) {\n      rightClickArgs = args;\n      \n      return Promise.resolve({\n        status:0,\n        value: null\n      })\n    }\n\n    this.client.api.useXpath()\n      .rightClick('//weblogin', function callback(result) {\n        assert.deepStrictEqual(rightClickArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b'])\n        assert.strictEqual(result.status, 0);\n      })\n\n    this.client.start(done);\n  });\n\n  it('client.rightClick() - element not interactable error - failed', function(done) {\n    let rightClickArgs;\n    this.client.transport.Actions.session.contextClick = function(args) {\n      rightClickArgs = args;\n      return Promise.resolve({\n        status: -1,\n        value: null,\n        error: new Error('Element could not be scrolled into view')\n      });\n    }\n\n    this.client.api.rightClick({\n      retryInterval: 50,\n      timeout: 100,\n      selector: '#weblogin'\n    }, function(result) {\n      assert.deepStrictEqual(rightClickArgs.args,['5cc459b8-36a8-3042-8b4a-258883ea642b'])\n      assert.strictEqual(result.status, -1);\n      assert.strictEqual(result.value.error,'An error occurred while running .rightClick() command on <#weblogin>: Element could not be scrolled into view')\n    });\n\n    this.client.start(done);\n  });\n\n\n\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testSendKeys.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('sendKeys', function() {\n\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.sendKeys()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/value',\n      method: 'POST',\n      postdata: {text: 'password', value: ['p', 'a', 's', 's', 'w', 'o', 'r', 'd']},\n      response: {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    });\n\n    this.client.api\n      .sendKeys('css selector', '#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .sendKeys('css selector', {\n        selector: '#weblogin',\n        timeout: 100\n      }, 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .sendKeys({\n        selector: '#weblogin',\n        timeout: 100\n      }, 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .sendKeys('#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testSetAttribute.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\n\ndescribe('setAttribute', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.setAttribute()', function(done) {\n    let commandArgs;\n\n    // eslint-disable-next-line\n    const fn = function(e,a,v){try{if(e&&typeof e.setAttribute=='function'){e.setAttribute(a,v);}return true;}catch(err){return{error:err.message,message:err.name+': '+err.message};}};\n    const script = 'var passedArgs = Array.prototype.slice.call(arguments,0); ' +\n      'return (' + fn.toString() + ').apply(window, passedArgs);';\n\n    this.client.transport.driver.executeScript = function(scriptFn, element, attr, value) {\n      //moveToArgs = args;\n      commandArgs = [scriptFn, element, attr, value];\n\n      return Promise.resolve({\n        status: 0\n      });\n    };\n\n    this.client.api.setAttribute('css selector', '#weblogin', 'disabled', 'true', function(result) {\n      assert.strictEqual(commandArgs.length, 4);\n      assert.strictEqual(commandArgs[0].replace(/\\s/g, ''), script.replace(/\\s/g, ''));\n      assert.deepStrictEqual(commandArgs[1], {\n        ELEMENT: '0'\n      });\n      assert.strictEqual(commandArgs[2], 'disabled');\n      assert.strictEqual(commandArgs[3], 'true');\n      assert.strictEqual(result.status, 0);\n    }).setAttribute('#weblogin', 'disabled', 0, function(result) {\n      assert.strictEqual(commandArgs.length, 4);\n      assert.strictEqual(commandArgs[0].replace(/\\s/g, ''), script.replace(/\\s/g, ''));\n      assert.deepStrictEqual(commandArgs[1], {\n        ELEMENT: '0'\n      });\n      assert.strictEqual(commandArgs[2], 'disabled');\n      assert.strictEqual(commandArgs[3], 0);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testSetPassword.js",
    "content": "const assert = require('assert');\nconst {Key} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('setPassword', function() {\n\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.setPassword()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/value',\n      method: 'POST',\n      postdata: {\n        text: Key.NULL + 'password',\n        value: [Key.NULL, 'p', 'a', 's', 's', 'w', 'o', 'r', 'd']\n      },\n      response: {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/clear',\n      method: 'POST',\n      response: {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    });\n\n    this.client.api\n      .setPassword('css selector', '#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .setPassword('css selector', {\n        selector: '#weblogin',\n        timeout: 100\n      }, 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .setPassword({\n        selector: '#weblogin',\n        timeout: 100\n      }, 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .setPassword('#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testSetPasswordReport.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst {Key} = require('selenium-webdriver');\nconst common = require('../../../../common.js');\nconst Mocks  = require('../../../../lib/command-mocks.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\nconst MockServer  = require('../../../../lib/mockserver.js');\n\ndescribe('setPassword report check', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => done());\n  });\n\n  after(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('client.setPassword() value redacted in rawHttpOutput', async function() {\n    let sendKeysPasswordMockCalled = false;\n    let sendKeysNormalMockCalled = false;\n    let globalReporterCalled = false;\n\n    Mocks.createNewW3CSession({\n      testName: 'Actions API demo tests'\n    });\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/clear',\n      method: 'POST',\n      statusCode: 200,\n      response: {\n        value: null\n      },\n      times: 2\n    });\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/value',\n      method: 'POST',\n      postdata: {text: Key.NULL + 'password', value: [Key.NULL, 'p', 'a', 's', 's', 'w', 'o', 'r', 'd']},\n      response: {\n        value: null\n      },\n      onRequest: () => {\n        sendKeysPasswordMockCalled = true;\n      }\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/value',\n      method: 'POST',\n      postdata: {text: 'simpletext', value: ['s', 'i', 'm', 'p', 'l', 'e', 't', 'e', 'x', 't']},\n      response: {\n        value: null\n      },\n      onRequest: () => {\n        sendKeysNormalMockCalled = true;\n      }\n    }, true);\n\n    const testsPath = [\n      path.join(__dirname, '../../../../sampletests/passwordValueRedacted/passwordValueRedacted.js')\n    ];\n\n    const globals = {\n      reporter(results) {\n        globalReporterCalled = true;\n\n        assert.strictEqual(sendKeysPasswordMockCalled, true);\n        assert.strictEqual(sendKeysNormalMockCalled, true);\n        assert.strictEqual(results.errmessages.length, 0);\n\n        const rawHttpOutput = results.modules.passwordValueRedacted.rawHttpOutput;\n        const requests = rawHttpOutput\n          .filter((req) => {\n            return req[1].includes('element/5cc459b8-36a8-3042-8b4a-258883ea642b/value') &&\n              req[1].includes('Request POST');\n          });\n\n        assert.strictEqual(requests.length, 2);\n\n        // First request (setPassword) should contain redacted value\n        assert.strictEqual(requests[0][2].includes('password'), false);\n        assert.strictEqual(requests[0][2].includes('*******'), true);\n\n        // Second request (setValue) should NOT contain redacted value\n        assert.strictEqual(requests[1][2].includes('simpletext'), true);\n        assert.strictEqual(requests[1][2].includes('*******'), false);\n      }\n    };\n\n    await NightwatchClient.runTests(testsPath, settings({\n      globals,\n      output_folder: 'output',\n      selenium_host: null\n    }));\n\n    assert.strictEqual(globalReporterCalled, true);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testSetValue.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\n\ndescribe('setValue', function() {\n\n  beforeEach(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.setValue()', function(done) {\n    \n     \n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/clear',\n      method: 'POST',\n      statusCode: 200,\n      response: {\n        value: null\n      }\n    });\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/value',\n      method: 'POST',\n      postdata: {text: 'password', value: ['p', 'a', 's', 's', 'w', 'o', 'r', 'd']},\n      response: {\n        value: null\n      }\n    });\n\n    this.client.api\n      .setValue('css selector', '#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .setValue('css selector', {\n        selector: '#weblogin',\n        timeout: 100\n      }, 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .setValue({\n        selector: '#weblogin',\n        timeout: 100\n      }, 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .setValue('#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      });\n\n    this.client.start(done);\n  });\n\n  it('client.setValue - non editable element', function(done) {\n    \n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/clear',\n      method: 'POST',\n      statusCode: 400,\n      response: {\n        value: {\n          error: 'invalid element state',\n          message: 'Unable to clear element that cannot be edited',\n          stacktrace: ''\n        }\n      }\n    });\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/value',\n      method: 'POST',\n      postdata: {text: 'password', value: ['p', 'a', 's', 's', 'w', 'o', 'r', 'd']},\n      response: {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    });\n\n    this.client.api.setValue('#weblogin', 'password', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n    \n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testSubmitForm.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('submitForm', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n\n  it('client.submitForm()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      }, true, true)\n    });\n\n    this.client.api.submitForm('#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    }).submitForm('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testTakeElementScreenshot.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\nconst randomImage =\n      '/9j/4AAQSkZJRgABAQAASABIAAD/4QBqRXhpZgAATU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAABJKGAAcAAAASAAAAUKABAAMAAAABAAEAAKACAAQAAAABAAABAKADAAQAAAABAAABAAAAAABBU0NJSQAAADEuMTUuMS0yMUj/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs';\n\ndescribe('takeElementScreenshot', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.takeElementScreenshot()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value:\n          randomImage\n      })\n    });\n\n    this.client.api\n      .takeElementScreenshot('#weblogin', function(result) {\n        assert.strictEqual(result.value, randomImage);\n      })\n      .takeElementScreenshot('css selector', '#weblogin', function(result) {\n        assert.strictEqual(result.value, randomImage);\n      })\n      .takeElementScreenshot('css selector', {\n        selector: '#weblogin',\n        timeout: 100\n      }, function(result) {\n        assert.strictEqual(result.value, randomImage);\n      });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testUncheck.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('.uncheck()', function () {\n  beforeEach(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.uncheck() will uncheck selected checkbox input', function (done) {\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/element/0/click',\n      'response': {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: true\n      })\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'checkbox'\n      })\n    });\n\n    this.client.api.uncheck('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    }).uncheck('#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.uncheck() will uncheck selected radio input', function (done) {\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/element/0/click',\n      'response': {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: true\n      })\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'radio'\n      })\n    });\n\n    this.client.api.uncheck('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    }).uncheck('#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.uncheck() will not click unselected checkbox element', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    }).addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'checkbox'\n      })\n    });\n\n    this.client.api.uncheck('css selector', '#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    }).uncheck('#weblogin', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testUploadFile.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('uploadFile', function() {\n\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.uploadFile()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '#choosefile'\n      },\n      response: {\n        sessionId: '1352110219202',\n        status: 0,\n        value: [\n          {\n            ELEMENT: '0'\n          }\n        ],\n        class: 'org.openqa.selenium.remote.Response',\n        hCode: 604376696\n      }\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/value',\n      method: 'POST',\n      postdata: {\n        text: '/file.js',\n        value: [\n          '/', 'f', 'i', 'l', 'e', '.', 'j', 's'\n        ]\n      },\n      response: {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    });\n\n    this.client.api\n      .uploadFile('css selector', '#choosefile', '/file.js', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .uploadFile('css selector', {\n        selector: '#choosefile',\n        timeout: 100\n      }, '/file.js', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .uploadFile({\n        selector: '#choosefile',\n        timeout: 100\n      }, '/file.js', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .uploadFile('#choosefile', '/file.js', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      });\n\n    this.client.start(done);\n  });\n});"
  },
  {
    "path": "test/src/api/commands/element/testWaitForElementNotPresent.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst {strictEqual} = assert;\nconst common = require('../../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\nconst MockServer = require('../../../../lib/mockserver.js');\n\n\ndescribe('waitForElementNotPresent', function () {\n  let commandResult;\n  let commandInstance;\n\n  function commandCallback(result, instance) {\n    commandResult = result;\n    commandInstance = instance;\n  }\n\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.waitForElementNotPresent() success', function () {\n    this.client.api.globals.waitForConditionPollInterval = 10;\n    this.client.api.waitForElementNotPresent('.weblogin', 50, 5, commandCallback);\n\n    return this.client.start(function(err) {\n      strictEqual(err, undefined);\n      assert.deepStrictEqual(commandResult.value, null);\n      strictEqual(commandInstance.executor.retries, 0);\n      strictEqual(commandInstance.expectedValue, 'not found');\n      strictEqual(commandInstance.rescheduleInterval, 5);\n      strictEqual(commandInstance.abortOnFailure, true);\n      assert.ok(commandInstance.message.startsWith('Element <.weblogin> was not present after'));\n    });\n  });\n\n  it('client.waitForElementNotPresent() failure', function () {\n    this.client.api.globals.waitForConditionPollInterval = 10;\n    this.client.api.waitForElementNotPresent('#weblogin', 15, commandCallback);\n\n    return this.client.start(function (err) {\n      assert.ok(err instanceof Error);\n      assert.deepStrictEqual(commandResult.value, [{ELEMENT: '0'}]);\n      strictEqual(err.message, `Timed out while waiting for element <#weblogin> to be removed for 15 milliseconds. - expected \"not found\" but got: \"found\" (${commandInstance.elapsedTime}ms)`);\n    });\n  });\n\n  it('client.waitForElementNotPresent() failure no abort', function () {\n    this.client.api.globals.waitForConditionPollInterval = 10;\n    this.client.api.waitForElementNotPresent('#weblogin', 15, false, commandCallback);\n\n    return this.client.start(function (err) {\n      strictEqual(commandResult.status, 0);\n      strictEqual(commandInstance.abortOnFailure, false);\n      strictEqual(commandInstance.elementId, null);\n    });\n  });\n\n  it('client.waitForElementNotPresent() failure no abort with custom interval', function () {\n    this.client.api.globals.waitForConditionPollInterval = 10;\n    this.client.api.waitForElementNotPresent('#weblogin', 15, 10, false, commandCallback);\n\n    this.client.api.waitForElementNotPresent('#weblogin', 15, 10, false, function(result, instance) {\n      strictEqual(result.status, 0);\n      strictEqual(instance.rescheduleInterval, 10);\n      strictEqual(instance.ms, 15);\n      strictEqual(instance.abortOnFailure, false);\n    });\n\n    return this.client.start(function (err) {\n      strictEqual(commandResult.status, 0);\n      strictEqual(commandInstance.ms, 15);\n      strictEqual(commandInstance.rescheduleInterval, 10);\n    });\n  });\n\n\n  it('client.waitForElementNotPresent() report should not contain error in case of success', async function() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      method: 'POST',\n      postdata: {\n        using: 'css selector',\n        value: '#badElement'\n      },\n      response: JSON.stringify({\n        value: []\n      }),\n      times: 2\n    });\n\n    const testsPath = [\n      path.join(__dirname, '../../../../sampletests/withwait/elementNotPresent.js')\n    ];\n\n    const globals = {\n      calls: 0,\n      waitForConditionTimeout: 10,\n      waitForConditionPollInterval: 10,\n      reporter(results) {\n        assert.strictEqual(globals.calls, 2);\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n        assert.ok('elementNotPresent' in results.modules);\n        assert.strictEqual(results.modulesWithEnv.default.elementNotPresent.completedSections.demoTest.commands[1].status, 'pass');\n        assert.strictEqual(results.modulesWithEnv.default.elementNotPresent.completedSections.demoTest.commands[2].status, 'fail');\n      }\n    };\n\n    await NightwatchClient.runTests(testsPath, settings({\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testWaitForElementNotVisible.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst {strictEqual} = assert;\n\ndescribe('waitForElementNotVisible', function () {\n  let commandResult;\n  let commandInstance;\n\n  function commandCallback(result, instance) {\n    commandResult = result;\n    commandInstance = instance;\n  }\n\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function () {\n    MockServer.removeMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST'\n    });\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.waitForElementNotVisible() success', function () {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    });\n\n    this.client.api.waitForElementNotVisible('#weblogin', 11, 5, commandCallback);\n\n    return this.client.start(function (err) {\n      strictEqual(err, undefined);\n      strictEqual(commandResult.value, false);\n    });\n  });\n\n  it('client.waitForElementNotVisible() failure', function () {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: true\n      })\n    });\n\n    this.client.api.waitForElementNotVisible('#weblogin', 15, 10, commandCallback);\n\n    return this.client.start(function (err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.abortOnFailure, true);\n      if (err.name !== 'NightwatchAssertError') {\n        throw err;\n      }\n\n      assert.strictEqual(commandResult.status, 0);\n      assert.strictEqual(err.message, `Timed out while waiting for element <#weblogin> to not be visible for 15 milliseconds. - expected \"not visible\" but got: \"visible\" (${commandInstance.elapsedTime}ms)`);\n    });\n  });\n\n  it('client.waitForElementNotVisible() success after retry', function () {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: true\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    }, true);\n\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    this.client.api.waitForElementNotVisible('#weblogin', 150, commandCallback);\n\n    return this.client.start(function (err) {\n      strictEqual(err, undefined);\n      assert.strictEqual(commandResult.status, 0);\n      assert.strictEqual(commandResult.value, false);\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/commands/element/testWaitForElementPresent.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('waitForElementPresent', function() {\n  beforeEach(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.waitForElementPresent() success', function(done) {\n    this.client.api.waitForElementPresent('#weblogin', 100, function(result, instance) {\n      assert.strictEqual(instance.expectedValue, 'found');\n      assert.strictEqual(result.status, 0);\n      assert.deepStrictEqual(result.value[0], {ELEMENT: '0'});\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.waitForElementPresent() with webdriver response success', function(done) {\n    Nightwatch.initW3CClient({\n    }).then(client => {\n      client.api.waitForElementPresent('#webdriver', 100, function(result, instance) {\n        assert.strictEqual(instance.expectedValue, 'found');\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value, [\n          {'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'}\n        ]);\n      });\n\n      client.start(done);\n    });\n\n  });\n\n  it('client.waitForElementPresent() failure with custom message', function(done) {\n    this.client.api.globals.waitForConditionPollInterval = 10;\n    this.client.api.waitForElementPresent('.weblogin', 15, function callback(result, instance) {\n      assert.ok(/^Element .weblogin found in (\\d+) milliseconds$/.test(instance.message));\n      assert.strictEqual(result.value, null);\n    }, 'Element %s found in %d milliseconds');\n\n    this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      if (err.name !== 'NightwatchAssertError') {\n        done(err);\n      } else {\n        done();\n      }\n    }).catch(done);\n  });\n\n  it('client.waitForElementPresent() failure with custom time message', function(done){\n    this.client.api.globals.waitForConditionPollInterval = 10;\n    this.client.api.waitForElementPresent('.weblogin', 15, function callback(result, instance){\n      assert.strictEqual(instance.message, 'Element .weblogin found in 15 milliseconds');\n    }, 'Element %s found in %d milliseconds');\n\n    this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      if (err.name !== 'NightwatchAssertError') {\n        done(err);\n      } else {\n        done();\n      }\n    }).catch(done);\n\n  });\n\n  it('client.waitForElementPresent() with custom message and no params', function(done) {\n    this.client.api.globals.waitForConditionPollInterval = 10;\n\n    this.client.api.waitForElementPresent({selector: '#weblogin'}, 'Element found');\n    this.client.start(function(err) {\n      if (err) {\n        done(err);\n      } else {\n        done();\n      }\n    }).catch(done);\n  });\n\n  it('client.waitForElementPresent() with no params', function(done) {\n    this.client.api.globals.waitForConditionPollInterval = 10;\n\n    this.client.api.waitForElementPresent('#weblogin');\n    this.client.start(function(err) {\n      assert.strictEqual(typeof err, 'undefined');\n      done();\n    }).catch(done);\n  });\n\n  it('client.waitForElementPresent() failure', function() {\n    this.client.api.globals.waitForConditionPollInterval = 10;\n\n    this.client.api.waitForElementPresent('.weblogin', 15, function callback(result) {\n      assert.strictEqual(result.value, null);\n    });\n\n    return this.client.start(function (err) {\n      assert.ok(err instanceof Error);\n      if (err.name !== 'NightwatchAssertError') {\n        throw err;\n      }\n    });\n  });\n\n  it('client.waitForElementPresent() failure no abort', function(done) {\n    this.client.api.waitForElementPresent('.weblogin', 15, 10, false, function callback(result) {\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(function(err) {\n      if (err && err.name !== 'NightwatchAssertError') {\n        done(err);\n      } else {\n        done();\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/element/testWaitForElementVisible.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('waitForElementVisible', function () {\n  beforeEach(function (done) {\n    CommandGlobals.beforeEach.call(this, done, {\n      output: false\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  let commandInstance;\n\n  it('client.waitForElementVisible() failure', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    });\n\n    this.client.api.globals.abortOnAssertionFailure = false;\n    this.client.api.globals.waitForConditionPollInterval = 10;\n    this.client.api.waitForElementVisible('#weblogin', 15, 10, function (result, instance) {\n      assert.deepStrictEqual(instance.args, [15, 10]);\n      assert.ok(instance.executor.retries >= 1);\n      assert.strictEqual(instance.message, 'Timed out while waiting for element <#weblogin> to be visible for 15 milliseconds.');\n      assert.strictEqual(instance.expectedValue, 'visible');\n      assert.strictEqual(instance.selector, '#weblogin');\n      assert.strictEqual(instance.strategy, 'css selector');\n      assert.strictEqual(instance.suppressNotFoundErrors, false);\n      assert.strictEqual(instance.__timeoutMs, 15);\n      assert.strictEqual(instance.throwOnMultipleElementsReturned, false);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, false);\n    });\n\n    this.client.start(function (err) {\n      if (err && err.name !== 'NightwatchAssertError') {\n        done(err);\n      } else {\n        done();\n      }\n    });\n  });\n\n  it('client.waitForElementVisible() fail with global timeout default', function () {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    });\n\n    this.client.api.globals.waitForConditionTimeout = 15;\n    this.client.api.globals.waitForConditionPollInterval = 10;\n    this.client.api.waitForElementVisible('#weblogin', function callback(result, instance) {\n      commandInstance = instance;\n      assert.strictEqual(instance.expectedValue, 'visible');\n      assert.strictEqual(instance.message, 'Timed out while waiting for element <#weblogin> to be visible for 15 milliseconds.');\n      assert.strictEqual(result.status, 0);\n    });\n\n    return this.client.start(function (err) {\n      if (!err) {\n        throw new Error('Expected error but got none');\n      }\n\n      if (err.name === 'NightwatchAssertError') {\n        assert.strictEqual(err.abortOnFailure, true);\n        assert.strictEqual(err.message, `Timed out while waiting for element <#weblogin> to be visible for 15 milliseconds. - expected \"visible\" but got: \"not visible\" (${commandInstance.elapsedTime}ms)`);\n\n        return;\n      }\n\n      throw err;\n    });\n  });\n\n  it('client.waitForElementVisible() fail with global timeout default and custom message', function () {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    });\n\n    this.client.api.globals.waitForConditionTimeout = 15;\n    this.client.api.globals.waitForConditionPollInterval = 10;\n    this.client.api.waitForElementVisible('#weblogin', function callback(result, instance) {\n      commandInstance = instance;\n      assert.strictEqual(instance.message, 'Test message <#weblogin> and a global 15 ms.');\n    }, 'Test message <%s> and a global %d ms.');\n\n    return this.client.start(function (err) {\n      if (!err) {\n        throw new Error('Expected error but got none');\n      }\n\n      if (err.name === 'NightwatchAssertError') {\n        assert.strictEqual(err.message, `Test message <#weblogin> and a global 15 ms. - expected \"visible\" but got: \"not visible\" (${commandInstance.elapsedTime}ms)`);\n\n        return;\n      }\n\n      throw err;\n    });\n  });\n\n  it('client.waitForElementVisible() fail with global timeout default and custom message with only time placeholder', function () {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    });\n\n    this.client.api.globals.waitForConditionTimeout = 15;\n    this.client.api.globals.waitForConditionPollInterval = 10;\n    this.client.api.waitForElementVisible('#weblogin', function callback(result, instance) {\n      commandInstance = instance;\n      assert.strictEqual(instance.message, 'Test message with a global 15 ms.');\n    }, 'Test message with a global %d ms.');\n\n    return this.client.start(function (err) {\n      if (!err) {\n        throw new Error('Expected error but got none');\n      }\n\n      if (err.name === 'NightwatchAssertError') {\n        assert.strictEqual(err.message, `Test message with a global 15 ms. - expected \"visible\" but got: \"not visible\" (${commandInstance.elapsedTime}ms)`);\n\n        return;\n      }\n\n      throw err;\n    });\n  });\n\n  it('client.waitForElementVisible() StaleElementReference error', function () {\n    MockServer\n      .addMock({\n        url: '/wd/hub/session/1352110219202/elements',\n        postdata: '{\"using\":\"css selector\",\"value\":\"#stale-element\"}',\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '99'}]\n        })\n      }, true)\n      .addMock({\n        url: '/wd/hub/session/1352110219202/execute/sync',\n        method: 'POST',\n        response: JSON.stringify({\n          value: {\n            error: 'stale element reference'\n          }\n        })\n      }, true)\n      .addMock({\n        url: '/wd/hub/session/1352110219202/elements',\n        postdata: '{\"using\":\"css selector\",\"value\":\"#stale-element\"}',\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '88'}]\n        })\n      }, true)\n      .addMock({\n        url: '/wd/hub/session/1352110219202/execute/sync',\n        method: 'POST',\n        response: JSON.stringify({\n          value: true\n        })\n      }, true);\n\n    this.client.api.waitForElementVisible('#stale-element', 110, 10, function callback(result, instance) {\n      assert.strictEqual(instance.elementId, '88');  // element id refreshed\n      assert.strictEqual(result.value, true);\n    });\n\n    return this.client.start(function (err) {\n      if (err) {\n        throw err;\n      }\n    });\n  });\n\n  it('client.waitForElementVisible() with element not found', function () {\n    let result;\n\n    this.client.settings.globals.waitForConditionPollInterval = 5;\n    this.client.api.waitForElementVisible('.weblogin', 11, function (res, instance) {\n      commandInstance = instance;\n      result = res;\n    });\n\n    return this.client.start(function (e) {\n      assert.strictEqual(result.value, null);\n      assert.strictEqual(result.status, -1);\n      assert.strictEqual(e.message, `Timed out while waiting for element <.weblogin> to be present for 11 milliseconds. - expected \"visible\" but got: \"not found\" (${commandInstance.elapsedTime}ms)`);\n    });\n  });\n\n  it('client.waitForElementVisible() success after retry', function () {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: false\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: true\n      })\n    }, true);\n\n    let commandResult;\n    let commandInstance;\n\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    this.client.api.waitForElementVisible('#weblogin', 110, function (result, instance) {\n      commandInstance = instance;\n      commandResult = result;\n    });\n\n    return this.client.start(function (err) {\n      assert.strictEqual(commandResult.value, true);\n      assert.strictEqual(commandInstance.executor.retries, 1);\n      assert.strictEqual(err, undefined);\n    });\n  });\n\n  it('client.waitForElementVisible() fail with no args and global timeout not set', function () {\n    this.client.api.globals.waitForConditionTimeout = null;\n\n    this.client.api.waitForElementVisible('foo');\n\n    return this.client.start(function (err) {\n      assert.ok(err instanceof Error);\n      assert.ok(err.message.includes('waitForElement expects second parameter to have a global default (waitForConditionTimeout) to be specified if not passed as the second parameter'));\n    });\n  });\n\n  it('client.waitForElementVisible() success with custom locator strategy', function () {\n    MockServer\n      .addMock({\n        url: '/wd/hub/session/1352110219202/elements',\n        postdata: {\n          using: 'xpath',\n          value: '//*div[2]/button'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '99'}]\n        })\n      }, true)\n      .addMock({\n        url: '/wd/hub/session/1352110219202/execute/sync',\n        method: 'POST',\n        response: JSON.stringify({\n          state: 'success',\n          status: 0,\n          value: true\n        })\n      }, true);\n\n    this.client.api.waitForElementVisible('xpath', '//*div[2]/button', function callback(result, instance) {\n      assert.strictEqual(instance.elementId, '99');\n      assert.strictEqual(result.value, true);\n    });\n\n    return this.client.start(function (err) {\n      if (err) {\n        throw err;\n      }\n    });\n  });\n\n  it('client.waitForElementVisible() success with selector and test message only', function () {\n    MockServer\n      .addMock({\n        url: '/wd/hub/session/1352110219202/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#web-login'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '99'}]\n        })\n      }, true)\n      .addMock({\n        url: '/wd/hub/session/1352110219202/execute/sync',\n        method: 'POST',\n        response: JSON.stringify({\n          state: 'success',\n          status: 0,\n          value: true\n        })\n      }, true);\n\n    this.client.api.waitForElementVisible('#web-login', 'Test message');\n\n    return this.client.start(function (err) {\n      if (err) {\n        throw err;\n      }\n    });\n  });\n\n  it('client.waitForElementVisible() success with appium client', function () {\n    MockServer\n      .addMock({\n        url: '/wd/hub/session/1352110219202/elements',\n        postdata: {\n          using: 'id',\n          value: 'com.app:id/web-login'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '99'}]\n        })\n      }, undefined, true)\n      .addMock({\n        url: '/wd/hub/session/1352110219202/element/99/displayed',\n        method: 'GET',\n        response: JSON.stringify({\n          value: true\n        })\n      }, undefined, true);\n\n    // Make appium client\n    this.client.api.options.selenium.use_appium = true;\n\n    assert.strictEqual(this.client.api.isAppiumClient(), true);\n\n    this.client.api.waitForElementVisible('id', 'com.app:id/web-login', function callback(result, instance) {\n      assert.strictEqual(instance.elementId, '99');\n      assert.strictEqual(result.value, true);\n    }).waitForElementVisible({selector: 'com.app:id/web-login', locateStrategy: 'id'}, function callback(result, instance) {\n      assert.strictEqual(instance.elementId, '99');\n      assert.strictEqual(result.value, true);\n    });\n\n    return this.client.start(function (err) {\n      if (err) {\n        throw err;\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/logs/testCaptureBrowserConsoleLogs.js",
    "content": "const assert = require('assert');\nconst common = require('../../../../common.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst cdp = common.require('transport/selenium-webdriver/cdp.js');\n\ndescribe('.captureBrowserConsoleLogs()', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.captureBrowserConsoleLogs()', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n\n      let expectedCdpConnection;\n      let expectedUserCallback;\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve();\n      };\n      client.transport.driver.onLogEvent = (cdpConnection, userCallback) => {\n        expectedCdpConnection = cdpConnection;\n        expectedUserCallback = userCallback;\n      };\n\n      //eslint-disable-next-line\n      const userCallback = (event) => {console.log(event)};\n      client.api.captureBrowserConsoleLogs(userCallback, function () {\n        assert.strictEqual(expectedCdpConnection, undefined);  // cdpConnection is mocked\n        assert.strictEqual(expectedUserCallback, userCallback);\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('browser.logs.captureBrowserConsoleLogs()', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      let expectedCdpConnection;\n      let expectedUserCallback;\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve();\n      };\n      client.transport.driver.onLogEvent = (cdpConnection, userCallback) => {\n        expectedCdpConnection = cdpConnection;\n        expectedUserCallback = userCallback;\n      };\n\n      //eslint-disable-next-line\n      const userCallback = (event) => {console.log(event)};\n      client.api.logs.captureBrowserConsoleLogs(userCallback, function () {\n        assert.strictEqual(expectedCdpConnection, undefined);  // cdpConnection is mocked\n        assert.strictEqual(expectedUserCallback, userCallback);\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('throws error without callback', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      client.api.captureBrowserConsoleLogs(undefined, function (result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'Callback is missing from .captureBrowserConsoleLogs() command.');\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('browser.captureBrowserConsoleLogs - driver not supported', function(done){\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      //eslint-disable-next-line\n      const userCallback = (event) => {console.log(event)};\n\n      client.api.captureBrowserConsoleLogs(userCallback, function(result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .captureBrowserConsoleLogs() is only supported in Chrome and Edge drivers');\n      });\n      client.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/logs/testCaptureBrowserExceptions.js",
    "content": "const assert = require('assert');\nconst common = require('../../../../common.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst Nightwatch = require('../../../../lib/nightwatch.js');\nconst cdp = common.require('transport/selenium-webdriver/cdp.js');\n\ndescribe('.captureBrowserExceptions()', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('browser.captureBrowserExceptions(callback)', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n\n      let expectedCdpConnection;\n      let expectedUserCallback;\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve();\n      };\n      client.transport.driver.onLogException = (cdpConnection, userCallback) => {\n        expectedCdpConnection = cdpConnection;\n        expectedUserCallback = userCallback;\n      };\n\n      //eslint-disable-next-line\n      const userCallback = (event) => {console.log(event)};\n      client.api.captureBrowserExceptions(userCallback, function () {\n        assert.strictEqual(expectedCdpConnection, undefined);  // cdpConnection is mocked\n        assert.strictEqual(expectedUserCallback, userCallback);\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('browser.logs.captureBrowserExceptions(callback)', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      let expectedCdpConnection;\n      let expectedUserCallback;\n\n      cdp.resetConnection();\n      client.transport.driver.createCDPConnection = function() {\n        return Promise.resolve();\n      };\n      client.transport.driver.onLogException = (cdpConnection, userCallback) => {\n        expectedCdpConnection = cdpConnection;\n        expectedUserCallback = userCallback;\n      };\n\n      //eslint-disable-next-line\n      const userCallback = (event) => {console.log(event)};\n      client.api.logs.captureBrowserExceptions(userCallback, function () {\n        assert.strictEqual(expectedCdpConnection, undefined);  // cdpConnection is mocked\n        assert.strictEqual(expectedUserCallback, userCallback);\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('throws error without callback', function (done) {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            browserName: 'chrome',\n            browserVersion: '92.0'\n          }\n        }\n      },\n      method: 'POST',\n      statusCode: 201\n    }, true);\n\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {}\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      client.api.captureBrowserExceptions(undefined, function (result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'Callback is missing from .captureBrowserExceptions() command.');\n      });\n\n      client.start(done);\n    });\n  });\n\n  it('browser.captureBrowserExceptions - driver not supported', function(done){\n    Nightwatch.initW3CClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      output: process.env.VERBOSE === '1',\n      silent: false\n    }).then(client => {\n      //eslint-disable-next-line\n      const userCallback = (event) => {console.log(event)};\n\n      client.api.captureBrowserExceptions(userCallback, function(result){\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.error, 'The command .captureBrowserExceptions() is only supported in Chrome and Edge drivers');\n      });\n      client.start(done);\n    });\n  });\n});"
  },
  {
    "path": "test/src/api/commands/logs/testGetLog.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getLog', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.logs.getSessionLog()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/se/log',\n      postdata: {\n        type: 'driver'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        status: 0,\n        value: [\n          {level: 'INFO', timestamp: 534557932, message: 'Driver log 1'},\n          {level: 650, timestamp: 534563132, message: 'Driver log 2'}\n        ]\n      })\n    }, true);\n\n    let logsReceived;\n    const api = this.client.api;\n\n    this.client.api.logs.getSessionLog('driver', function(result) {\n      logsReceived = result.value;\n\n      assert.strictEqual(this, api);\n    });\n\n    this.client.start(function(err) {\n      try {\n        assert.strictEqual(err, undefined);\n\n        assert.strictEqual(Array.isArray(logsReceived), true, 'result is array');\n        assert.strictEqual(logsReceived.length, 2);\n        assert.strictEqual(logsReceived[0].level.name, 'INFO');\n        assert.strictEqual(logsReceived[0].level.value, 800);\n        assert.strictEqual(logsReceived[1].level.name, 'FINE');\n        assert.strictEqual(logsReceived[1].level.value, 500);\n        assert.strictEqual(logsReceived[0].message, 'Driver log 1');\n        assert.strictEqual(logsReceived[1].message, 'Driver log 2');\n\n        done();\n      } catch (e) {\n        done(e);\n      }\n    });\n  });\n\n  it('client.logs.getSessionLog() implicit', function(done) {\n    let logsReceived;\n    this.client.api.logs.getSessionLog(function(result) {\n      logsReceived = result.value;\n    });\n\n    this.client.start(function(err) {\n      try {\n        assert.strictEqual(err, undefined);\n        assert.strictEqual(logsReceived.length, 2);\n        assert.strictEqual(Array.isArray(logsReceived), true, 'result is array');\n        assert.strictEqual(logsReceived[0].message, 'Test log');\n\n        done();\n      } catch (e) {\n        done(e);\n      }\n    });\n  });\n\n  it('client.logs.getSessionLog() with callback rejecting a Promise', function() {\n    this.client.api.logs.getSessionLog('browser', function(result) {\n      return new Promise((resolve, reject) => {\n        reject(new Error('test error'));\n      });\n    });\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.message, 'Error while running \"logs.getSessionLog\" command: test error');\n    });\n  });\n\n  it('client.logs.getSessionLog() with callback returning a Promise', function() {\n    let logsResult;\n    this.client.api.logs.getSessionLog('browser', function(result) {\n      logsResult = result.value;\n\n      return new Promise((resolve) => {\n        resolve();\n      });\n    });\n\n    return this.client.start(function() {\n      assert.strictEqual(Array.isArray(logsResult), true, 'result is array');\n      assert.strictEqual(logsResult.length, 2);\n    });\n  });\n\n  it('client.getLog()', function(done) {\n    const api = this.client.api;\n    this.client.api.getLog('browser', function(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(Array.isArray(result), true, 'result is array');\n      assert.strictEqual(result.length, 2);\n      assert.strictEqual(result[0].message, 'Test log');\n      assert.strictEqual(result[1].message, 'Test log2');\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.getLog() implicit', function(done) {\n    this.client.api.getLog(function(result) {\n      assert.strictEqual(result.length, 2);\n      assert.strictEqual(Array.isArray(result), true, 'result is array');\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.getLog() with callback rejecting a Promise', function() {\n    this.client.api.getLog('browser', function(result) {\n      return new Promise((resolve, reject) => {\n        reject(new Error('test error'));\n      });\n    });\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.message, 'Error while running \"getLog\" command: test error');\n    });\n  });\n\n  it('client.getLog() with callback returning a Promise', function() {\n    let commandResult;\n    this.client.api.getLog('browser', function(result) {\n      commandResult = result;\n\n      return new Promise((resolve, reject) => {\n        resolve();\n      });\n    });\n\n    return this.client.start(function(err) {\n      assert.strictEqual(Array.isArray(commandResult), true, 'result is array');\n      assert.strictEqual(commandResult.length, 2);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/logs/testGetLogTypes.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('getLogTypes', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.getLogTypes()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/se/log/types',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: ['browser', 'har']\n      })\n    }, true, true);\n\n    const api = this.client.api;\n\n    this.client.api\n      .getLogTypes(function callback(result) {\n        assert.strictEqual(this, api);\n        assert.ok(Array.isArray(result));\n        assert.strictEqual(result.length, 2);\n        assert.strictEqual(result[0], 'browser');\n        assert.strictEqual(result[1], 'har');\n      })\n      .logs.getSessionLogTypes(function callback(result) {\n        const availableLogTypes = result.value;\n\n        assert.strictEqual(this, api);\n        assert.ok(Array.isArray(availableLogTypes));\n        assert.strictEqual(availableLogTypes.length, 2);\n        assert.strictEqual(availableLogTypes[0], 'browser');\n        assert.strictEqual(availableLogTypes[1], 'har');\n      });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/logs/testIsLogAvailable.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('isLogAvailable', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function () {\n    MockServer.removeMock({\n      url: '/wd/hub/session/1352110219202/se/log/types',\n      method: 'GET'\n    });\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.logs.isSessionLogAvailable()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/se/log/types',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: ['browser', 'har']\n      })\n    });\n\n    const api = this.client.api;\n\n    this.client.api\n      .logs.isSessionLogAvailable('unknown', function callback(result) {\n        const isAvailable = result.value;\n\n        assert.strictEqual(this, api);\n        assert.strictEqual(isAvailable, false);\n      })\n      .logs.isSessionLogAvailable('browser', function callback(result) {\n        const isAvailable = result.value;\n\n        assert.strictEqual(typeof isAvailable, 'boolean');\n        assert.strictEqual(isAvailable, true);\n      });\n\n    this.client.start(done);\n  });\n\n  it('client.logs.isSessionLogAvailable() failure', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/se/log/types',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: {'message': 'Session not started or terminated'}\n      })\n    });\n\n    this.client.api\n      .logs.isSessionLogAvailable('unknown', function callback(result) {\n        const isAvailable = result.value;\n\n        assert.strictEqual(typeof isAvailable === 'boolean', true);\n        assert.strictEqual(isAvailable, false);\n      })\n      .logs.isSessionLogAvailable('browser', function callback(result) {\n        const isAvailable = result.value;\n\n        assert.strictEqual(typeof isAvailable === 'boolean', true);\n        assert.strictEqual(isAvailable, false);\n      });\n\n    this.client.start(done);\n  });\n\n  it('client.isLogAvailable()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/se/log/types',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: ['browser', 'har']\n      })\n    });\n\n    const api = this.client.api;\n\n    this.client.api\n      .isLogAvailable('unknown', function callback(result) {\n        assert.strictEqual(this, api);\n        assert.strictEqual(result, false);\n      })\n      .isLogAvailable('browser', function callback(result) {\n        assert.strictEqual(typeof result, 'boolean');\n        assert.strictEqual(result, true);\n      });\n\n    this.client.start(done);\n  });\n\n  it('client.isLogAvailable() failure', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/se/log/types',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: {'message': 'Session not started or terminated'}\n      })\n    });\n\n    this.client.api.isLogAvailable('unknown', function callback(result) {\n      assert.strictEqual(typeof result === 'boolean', true);\n      assert.strictEqual(result, false);\n    })\n      .isLogAvailable('browser', function callback(result) {\n        assert.strictEqual(typeof result === 'boolean', true);\n        assert.strictEqual(result, false);\n      });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/testPageSource.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../lib/globals/commands.js');\n\ndescribe('pageSource', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.pageSource()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/source',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: '<html>Sample HTML</html>'\n      })\n    });\n\n    this.client.api.pageSource(function callback(result) {\n      assert.strictEqual(result.value, '<html>Sample HTML</html>');\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n});"
  },
  {
    "path": "test/src/api/commands/testSendKeys.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../lib/globals/commands.js');\n\ndescribe('sendKeys', function() {\n \n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done, {\n      output: false,\n      globals: {\n        waitForConditionPollInterval: 10,\n        waitForConditionTimeout: 11\n      }\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.sendKeys()', function(done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/value',\n      method: 'POST',\n      postdata: {'text': 'password', 'value': ['p', 'a', 's', 's', 'w', 'o', 'r', 'd']},\n      response: {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    });\n\n    this.client.api\n      .sendKeys('css selector', '#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .sendKeys('css selector', {\n        selector: '#weblogin',\n        timeout: 100\n      }, 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .sendKeys({\n        selector: '#weblogin',\n        timeout: 100\n      }, 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .sendKeys('#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .sendKeys('#weblogin', undefined, function callback(result) {\n        assert.strictEqual(result.status, -1);\n        assert.ok(result.value.message.includes('each key must be a number'))\n      })\n      .sendKeys('#weblogin', ['password', undefined], function callback(result) {\n        assert.strictEqual(result.status, -1);\n        assert.ok(result.value.message.includes('each key must be a number'))\n      })\n      .sendKeys('#weblogin', null, function callback(result) {\n        assert.strictEqual(result.status, -1);\n        assert.ok(result.value.message.includes('each key must be a number'))\n      })\n      .sendKeys('#weblogin', ['password', null], function callback(result) {\n        assert.strictEqual(result.status, -1);\n        assert.ok(result.value.message.includes('each key must be a number'))\n      });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/testUpdateValue.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../lib/globals/commands.js');\n\ndescribe('updateValue', function() {\n\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.updateValue()', function(done) {\n    let clearValueCalled = false;\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/clear',\n      method: 'POST',\n      postdata: {},\n      response: {\n        value: null,\n        status: 0\n      },\n      onResponse() {\n        clearValueCalled = true;\n      }\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/value',\n      method: 'POST',\n      postdata: {text: 'password', value: ['p', 'a', 's', 's', 'w', 'o', 'r', 'd']},\n      response: {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    });\n\n    this.client.api\n      .updateValue('css selector', '#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .updateValue('css selector', {\n        selector: '#weblogin',\n        timeout: 100\n      }, 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .updateValue({\n        selector: '#weblogin',\n        timeout: 100\n      }, 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .updateValue('#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n      })\n      .updateValue('#weblogin', 'password', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.strictEqual(clearValueCalled, true);\n      });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/assert/testElementAssertions.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element() assert commands', function () {\n  this.timeout(10000);\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, () => {\n      this.client.isES6AsyncTestcase = true;\n      done();\n    });\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element() enabled assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/enabled',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true, true);\n\n    this.client.options.globals.retryAssertionTimeout = 0;\n\n    const signupElement = this.client.api.element('#signupSection');\n    const assertPromise = signupElement.assert.enabled();\n    const notAssertPromise = signupElement.assert.not.enabled();\n\n    assert.strictEqual(assertPromise instanceof Element, false);\n    assert.strictEqual(assertPromise instanceof Promise, true);\n    assert.strictEqual(typeof assertPromise.find, 'undefined');\n\n    await assertPromise;\n    try {\n      await notAssertPromise;\n      assert.fail('NightwatchAssertError expected');\n    } catch (err) {\n      assert.strictEqual(err.name, 'NightwatchAssertError');\n    }\n  });\n\n  it('test .element() not enabled assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/enabled',\n      method: 'GET',\n      response: JSON.stringify({\n        value: false\n      })\n    }, true, true);\n\n    this.client.options.globals.retryAssertionTimeout = 0;\n\n    const signupElement = this.client.api.element('#signupSection');\n    const assertPromise = signupElement.assert.enabled();\n    const notAssertPromise = signupElement.assert.not.enabled();\n\n    assert.strictEqual(assertPromise instanceof Element, false);\n    assert.strictEqual(assertPromise instanceof Promise, true);\n    assert.strictEqual(typeof assertPromise.find, 'undefined');\n\n    await notAssertPromise;\n    try {\n      await assertPromise;\n      assert.fail('NightwatchAssertError expected');\n    } catch (err) {\n      assert.strictEqual(err.name, 'NightwatchAssertError');\n    }\n  });\n\n  it('test .element() selected assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true, true);\n\n    this.client.options.globals.retryAssertionTimeout = 0;\n\n    const signupElement = this.client.api.element('#signupSection');\n    const assertPromise = signupElement.assert.selected();\n    const notAssertPromise = signupElement.assert.not.selected();\n\n    assert.strictEqual(assertPromise instanceof Element, false);\n    assert.strictEqual(assertPromise instanceof Promise, true);\n    assert.strictEqual(typeof assertPromise.find, 'undefined');\n\n    await assertPromise;\n    try {\n      await notAssertPromise;\n      assert.fail('NightwatchAssertError expected');\n    } catch (err) {\n      assert.strictEqual(err.name, 'NightwatchAssertError');\n    }\n  });\n\n  it('test .element() visible assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true, true);\n\n    this.client.options.globals.retryAssertionTimeout = 0;\n\n    const signupElement = this.client.api.element('#signupSection');\n    const assertPromise = signupElement.assert.visible();\n    const notAssertPromise = signupElement.assert.not.visible();\n\n    assert.strictEqual(assertPromise instanceof Element, false);\n    assert.strictEqual(assertPromise instanceof Promise, true);\n    assert.strictEqual(typeof assertPromise.find, 'undefined');\n\n    await assertPromise;\n    try {\n      await notAssertPromise;\n      assert.fail('NightwatchAssertError expected');\n    } catch (err) {\n      assert.strictEqual(err.name, 'NightwatchAssertError');\n    }\n  });\n\n  it('test .element() hasDescendants assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true, true);\n\n    this.client.options.globals.retryAssertionTimeout = 0;\n\n    const signupElement = this.client.api.element('#signupSection');\n    const assertPromise = signupElement.assert.hasDescendants();\n    const notAssertPromise = signupElement.assert.not.hasDescendants();\n\n    assert.strictEqual(assertPromise instanceof Element, false);\n    assert.strictEqual(assertPromise instanceof Promise, true);\n    assert.strictEqual(typeof assertPromise.find, 'undefined');\n\n    await assertPromise;\n    try {\n      await notAssertPromise;\n      assert.fail('NightwatchAssertError expected');\n    } catch (err) {\n      assert.strictEqual(err.name, 'NightwatchAssertError');\n    }\n  });\n\n  it('test .element() present assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true, true);\n\n    this.client.options.globals.retryAssertionTimeout = 0;\n\n    const signupElement = this.client.api.element('#signupSection');\n    const assertPromise = signupElement.assert.present();\n    const notAssertPromise = signupElement.assert.not.present();\n\n    assert.strictEqual(assertPromise instanceof Element, false);\n    assert.strictEqual(assertPromise instanceof Promise, true);\n    assert.strictEqual(typeof assertPromise.find, 'undefined');\n\n    await assertPromise;\n    try {\n      await notAssertPromise;\n      assert.fail('NightwatchAssertError expected');\n    } catch (err) {\n      assert.strictEqual(err.name, 'NightwatchAssertError');\n    }\n  });\n\n  it('test .element() hasClass assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true, true);\n\n    this.client.options.globals.retryAssertionTimeout = 0;\n\n    const signupElement = this.client.api.element('#signupSection');\n    const assertPromise = signupElement.assert.hasClass('signup');\n    const notAssertPromise = signupElement.assert.not.hasClass('signup');\n\n    assert.strictEqual(assertPromise instanceof Element, false);\n    assert.strictEqual(assertPromise instanceof Promise, true);\n    assert.strictEqual(typeof assertPromise.find, 'undefined');\n\n    await assertPromise;\n\n    try {\n      await notAssertPromise;\n      assert.fail('AssertionError expected');\n    } catch (err) {\n      assert.strictEqual(err.name, 'NightwatchAssertError');\n    }\n  });\n\n  xit('test .element() hasAttribute assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true, true);\n\n    this.client.options.globals.retryAssertionTimeout = 0;\n\n    const signupElement = this.client.api.element('#signupSection');\n    const assertPromise = signupElement.assert.hasAttribute('role');\n    const notAssertPromise = signupElement.assert.not.hasAttribute('role');\n\n    assert.strictEqual(assertPromise instanceof Element, false);\n    assert.strictEqual(assertPromise instanceof Promise, true);\n    assert.strictEqual(typeof assertPromise.find, 'undefined');\n\n    await assertPromise;\n\n    try {\n      await notAssertPromise;\n      assert.fail('AssertionError expected');\n    } catch (err) {\n      assert.strictEqual(err.name, 'NightwatchAssertError');\n    }\n  });\n});"
  },
  {
    "path": "test/src/api/commands/web-element/testCheck.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().check() command', function() {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().check() will check checkbox if not selected', async function () {\n    let nCallsToClick = 0;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      }),\n      onRequest(_) {\n        nCallsToClick++;\n      }\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: false\n      })\n    }, true);\n\n    // For returning 'checkbox' from getAttribute for type attribute\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'checkbox'\n      })\n    }, true);\n\n    const resultPromise = await this.client.api.element('#signupSection').check();\n\n    // Click command should have been used one time to uncheck\n    assert.strictEqual(nCallsToClick, 1);\n\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().check() will check radio input if not selected', async function () {\n    let nCallsToClick = 0;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      }),\n      onRequest(_) {\n        nCallsToClick++;\n      }\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: false\n      })\n    }, true);\n\n    // For returning 'radio' from getAttribute for type attribute\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'radio'\n      })\n    }, true);\n\n    const resultPromise = await this.client.api.element('#signupSection').check();\n\n    // Click command should have been used one time to uncheck\n    assert.strictEqual(nCallsToClick, 1);\n\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().check() will not check radio input if type not a checkbox or radio input', async function () {\n    let nCallsToClick = 0;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      }),\n      onRequest(_) {\n        nCallsToClick++;\n      }\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: false\n      })\n    }, true);\n\n    // For returning 'submit' from getAttribute for type attribute\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'submit'\n      })\n    }, true);\n\n    const resultPromise = await this.client.api.element('#signupSection').check();\n\n    // Click command should have been used one time to uncheck\n    assert.strictEqual(nCallsToClick, 0);\n\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().check() will not click if checked already', async function () {\n    let nCallsToClick = 0;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      }),\n      onRequest(_) {\n        nCallsToClick++;\n      }\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    // For returning 'radio' from getAttribute for type attribute\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'radio'\n      })\n    }, true);\n\n    const resultPromise = await this.client.api.element('#signupSection').check();\n\n    // Click command should not have been executed since element is unchecked already\n    assert.strictEqual(nCallsToClick, 0);\n    \n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/commands/web-element/testClear.js",
    "content": "const assert = require('assert');\nconst {WebElement, Key} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().clear() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().clear()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/clear',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').clear();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().find().clear()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/clear',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').clear();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '1');\n  });\n\n  it('test .element.find().clear()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/clear',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').clear();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().clear() with fallback sending keys', async function() {\n    let sendKeysMockCalled = false;\n\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/clear',\n        method: 'POST',\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/0/property/value',\n        method: 'GET',\n        response: {value: 'sample'}\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/0/value',\n        method: 'POST',\n        response: {value: null},\n        onRequest(_, requestData) {\n          assert.strictEqual(requestData.text, Array(6).fill(Key.BACK_SPACE).join(''));\n          sendKeysMockCalled = true;\n        }\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').clear();\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    assert.strictEqual(sendKeysMockCalled, true);\n  });\n\n  it('test .element().clear() with fallback not sending keys when clear working correctly', async function() {\n    let sendKeysMockCalled = false;\n\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/clear',\n        method: 'POST',\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/0/property/value',\n        method: 'GET',\n        response: {value: ''}\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/0/value',\n        method: 'POST',\n        response: {value: null},\n        onRequest() {\n          sendKeysMockCalled = true;\n        }\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').clear();\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    assert.strictEqual(sendKeysMockCalled, false);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testClick.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().click() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().click()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').click();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().find().click()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').click();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '1');\n  });\n\n  it('test .element.find().click()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').click();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testClickAndHold.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().clickAndHold() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().clickAndHold()', async function() {\n    let pressAndHoldArgs;\n    this.client.transport.Actions.session.pressAndHold = function(args) {\n      pressAndHoldArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element('#signupSection').clickAndHold();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await pressAndHoldArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n  });\n\n  it('test .element().find().clickAndHold()', async function() {\n    let pressAndHoldArgs;\n    this.client.transport.Actions.session.pressAndHold = function(args) {\n      pressAndHoldArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').clickAndHold();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '1');\n\n    const webElementArg = await pressAndHoldArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '1');\n  });\n\n  it('test .element.find().clickAndHold()', async function() {\n    let pressAndHoldArgs;\n    this.client.transport.Actions.session.pressAndHold = function(args) {\n      pressAndHoldArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element.find('#signupSection').clickAndHold();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await pressAndHoldArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testDoubleClick.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().doubleClick() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().doubleClick()', async function() {\n    let doubleClickArgs;\n    this.client.transport.Actions.session.doubleClick = function(args) {\n      doubleClickArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element('#signupSection').doubleClick();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await doubleClickArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n  });\n\n  it('test .element().find().doubleClick()', async function() {\n    let doubleClickArgs;\n    this.client.transport.Actions.session.doubleClick = function(args) {\n      doubleClickArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').doubleClick();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '1');\n\n    const webElementArg = await doubleClickArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '1');\n  });\n\n  it('test .element.find().doubleClick()', async function() {\n    let doubleClickArgs;\n    this.client.transport.Actions.session.doubleClick = function(args) {\n      doubleClickArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element.find('#signupSection').doubleClick();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await doubleClickArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testDragAndDrop.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().dragAndDrop(WebElement) command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().dragAndDrop()', async function() {\n    let dragElementArgs;\n    this.client.transport.Actions.session.dragElement = function(args) {\n      dragElementArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const webLoginWebElement = await this.client.api.element('#weblogin');\n    const resultPromise = this.client.api.element('#signupSection').dragAndDrop(webLoginWebElement);\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await dragElementArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n    assert.strictEqual(dragElementArgs.args[1], webLoginWebElement);\n  });\n\n  it('test .element().dragAndDrop(elementId)', async function() {\n    let dragElementArgs;\n    this.client.transport.Actions.session.dragElement = function(args) {\n      dragElementArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const webLoginElementId = await this.client.api.element('#weblogin').getId();\n    const resultPromise = this.client.api.element('#signupSection').dragAndDrop(webLoginElementId);\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await dragElementArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n    assert.strictEqual(dragElementArgs.args[1], webLoginElementId);\n  });\n\n  it('test .element().dragAndDrop({x, y})', async function() {\n    let dragElementArgs;\n    this.client.transport.Actions.session.dragElement = function(args) {\n      dragElementArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element('#signupSection').dragAndDrop({x: 100, y: 200});\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await dragElementArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n    assert.deepStrictEqual(dragElementArgs.args[1], {x: 100, y: 200});\n  });\n\n  it('test .element().find().dragAndDrop(WebElement)', async function() {\n    let dragElementArgs;\n    this.client.transport.Actions.session.dragElement = function(args) {\n      dragElementArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const webLoginWebElement = await this.client.api.element('#weblogin');\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').dragAndDrop(webLoginWebElement);\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '1');\n\n    const webElementArg = await dragElementArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '1');\n    assert.strictEqual(dragElementArgs.args[1], webLoginWebElement);\n  });\n\n  it('test .element.find().dragAndDrop()', async function() {\n    let dragElementArgs;\n    this.client.transport.Actions.session.dragElement = function(args) {\n      dragElementArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const webLoginWebElement = await this.client.api.element('#weblogin');\n    const resultPromise = this.client.api.element.find('#signupSection').dragAndDrop(webLoginWebElement);\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await dragElementArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n    assert.strictEqual(dragElementArgs.args[1], webLoginWebElement);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testElement.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('.element() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element()', async function() {\n    const signupElement = this.client.api.element('#signupSection');\n    assert.strictEqual(signupElement instanceof Element, true);\n    assert.strictEqual(await signupElement.getId(), '0');\n    assert.strictEqual(typeof signupElement.find, 'function');\n    assert.strictEqual(typeof signupElement.findByRole, 'function');\n    assert.strictEqual(typeof signupElement.assert, 'object');\n\n    const signupWebElement = await signupElement;\n    assert.strictEqual(signupWebElement instanceof WebElement, true);\n    assert.strictEqual(await signupWebElement.getId(), '0');\n    assert.strictEqual(typeof signupWebElement.find, 'undefined');\n    assert.strictEqual(typeof signupWebElement.assert, 'undefined');\n    assert.strictEqual(typeof signupWebElement.click, 'function');\n    assert.strictEqual(typeof signupWebElement.sendKeys, 'function');\n    assert.strictEqual(typeof signupWebElement.getDriver, 'function');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFind.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().find() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().find()', async function() {\n    const helpBtnElement = this.client.api.element('#signupSection').find('#helpBtn');\n    assert.strictEqual(helpBtnElement instanceof Element, true);\n    assert.strictEqual(await helpBtnElement.getId(), '1');\n\n    const helpBtnWebElement = await helpBtnElement;\n    assert.strictEqual(helpBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await helpBtnWebElement.getId(), '1');\n  });\n\n  it('test .element().get()', async function() {\n    const helpBtnElement = this.client.api.element('#signupSection').get('#helpBtn');\n    assert.strictEqual(helpBtnElement instanceof Element, true);\n    assert.strictEqual(await helpBtnElement.getId(), '1');\n\n    const helpBtnWebElement = await helpBtnElement;\n    assert.strictEqual(helpBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await helpBtnWebElement.getId(), '1');\n  });\n\n  it('test .element().findElement()', async function() {\n    const helpBtnElement = this.client.api.element('#signupSection').findElement('#helpBtn');\n    assert.strictEqual(helpBtnElement instanceof Element, true);\n    assert.strictEqual(await helpBtnElement.getId(), '1');\n\n    const helpBtnWebElement = await helpBtnElement;\n    assert.strictEqual(helpBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await helpBtnWebElement.getId(), '1');\n  });\n\n  it('test .element().find(selectorObject)', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'xpath',\n        value: '//*[id=\"helpBtn\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '2'}]\n      })\n    }, true);\n\n    const helpBtnElement = this.client.api.element('#signupSection').find({\n      locateStrategy: 'xpath', selector: '//*[id=\"helpBtn\"]'});\n    assert.strictEqual(helpBtnElement instanceof Element, true);\n    assert.strictEqual(await helpBtnElement.getId(), '2');\n\n    const helpBtnWebElement = await helpBtnElement;\n    assert.strictEqual(helpBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await helpBtnWebElement.getId(), '2');\n  });\n\n  it('test .element.find()', async function() {\n    const signupElement = this.client.api.element.find('#signupSection');\n    assert.strictEqual(signupElement instanceof Element, true);\n    assert.strictEqual(await signupElement.getId(), '0');\n\n    const signupWebElement = await signupElement;\n    assert.strictEqual(signupWebElement instanceof WebElement, true);\n    assert.strictEqual(await signupWebElement.getId(), '0');\n  });\n\n  it('test .element.get()', async function() {\n    const signupElement = this.client.api.element.get('#signupSection');\n    assert.strictEqual(signupElement instanceof Element, true);\n    assert.strictEqual(await signupElement.getId(), '0');\n\n    const signupWebElement = await signupElement;\n    assert.strictEqual(signupWebElement instanceof WebElement, true);\n    assert.strictEqual(await signupWebElement.getId(), '0');\n  });\n\n  it('test .element.findElement()', async function() {\n    const signupElement = this.client.api.element.findElement('#signupSection');\n    assert.strictEqual(signupElement instanceof Element, true);\n    assert.strictEqual(await signupElement.getId(), '0');\n\n    const signupWebElement = await signupElement;\n    assert.strictEqual(signupWebElement instanceof WebElement, true);\n    assert.strictEqual(await signupWebElement.getId(), '0');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindAll.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().findAll() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().findAll()', async function() {\n    const btnElements = this.client.api.element('#signupSection').findAll('.btn');\n    assert.strictEqual(btnElements instanceof Element, false);\n    assert.strictEqual(typeof btnElements.find, 'undefined');\n    assert.strictEqual(typeof btnElements.click, 'undefined');\n\n    assert.strictEqual(btnElements instanceof Promise, false);\n    assert.strictEqual(typeof btnElements.then, 'function');\n    assert.strictEqual(typeof btnElements.nth, 'function');\n    assert.strictEqual(typeof btnElements.count, 'function');\n\n    const btnWEbElements = await btnElements;\n    assert.strictEqual(btnWEbElements.length, 3);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '1');\n  });\n\n  it('test .element().getAll()', async function() {\n    const btnElements = this.client.api.element('#signupSection').getAll('.btn');\n    assert.strictEqual(btnElements instanceof Element, false);\n    assert.strictEqual(typeof btnElements.find, 'undefined');\n    assert.strictEqual(typeof btnElements.click, 'undefined');\n\n    assert.strictEqual(btnElements instanceof Promise, false);\n    assert.strictEqual(typeof btnElements.then, 'function');\n    assert.strictEqual(typeof btnElements.nth, 'function');\n    assert.strictEqual(typeof btnElements.count, 'function');\n\n    const btnWEbElements = await btnElements;\n    assert.strictEqual(btnWEbElements.length, 3);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '1');\n  });\n\n  it('test .element().findElements()', async function() {\n    const btnElements = this.client.api.element('#signupSection').findElements('.btn');\n    assert.strictEqual(btnElements instanceof Element, false);\n    assert.strictEqual(typeof btnElements.find, 'undefined');\n    assert.strictEqual(typeof btnElements.click, 'undefined');\n\n    assert.strictEqual(btnElements instanceof Promise, false);\n    assert.strictEqual(typeof btnElements.then, 'function');\n    assert.strictEqual(typeof btnElements.nth, 'function');\n    assert.strictEqual(typeof btnElements.count, 'function');\n\n    const btnWEbElements = await btnElements;\n    assert.strictEqual(btnWEbElements.length, 3);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '1');\n  });\n\n  it('test .element().findAll(selectorObject)', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'xpath',\n        value: '//*[id=\"helpBtn\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const helpBtnElements = this.client.api.element('#signupSection').findAll({\n      locateStrategy: 'xpath', selector: '//*[id=\"helpBtn\"]'});\n    assert.strictEqual(helpBtnElements instanceof Element, false);\n    assert.strictEqual(typeof helpBtnElements.find, 'undefined');\n    assert.strictEqual(typeof helpBtnElements.click, 'undefined');\n\n    assert.strictEqual(helpBtnElements instanceof Promise, false);\n    assert.strictEqual(typeof helpBtnElements.then, 'function');\n    assert.strictEqual(typeof helpBtnElements.nth, 'function');\n    assert.strictEqual(typeof helpBtnElements.count, 'function');\n\n    const btnWEbElements = await helpBtnElements;\n    assert.strictEqual(btnWEbElements.length, 2);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '2');\n  });\n\n  it('test .element.findAll()', async function() {\n    const webLoginElements = this.client.api.element.findAll('#weblogin');\n    assert.strictEqual(webLoginElements instanceof Element, false);\n    assert.strictEqual(typeof webLoginElements.find, 'undefined');\n    assert.strictEqual(typeof webLoginElements.click, 'undefined');\n\n    assert.strictEqual(webLoginElements instanceof Promise, false);\n    assert.strictEqual(typeof webLoginElements.then, 'function');\n    assert.strictEqual(typeof webLoginElements.nth, 'function');\n    assert.strictEqual(typeof webLoginElements.count, 'function');\n\n    const btnWEbElements = await webLoginElements;\n    assert.strictEqual(btnWEbElements.length, 2);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '5cc459b8-36a8-3042-8b4a-258883ea642b');\n  });\n\n  it('test .element.getAll()', async function() {\n    const webLoginElements = this.client.api.element.getAll('#weblogin');\n    assert.strictEqual(webLoginElements instanceof Element, false);\n    assert.strictEqual(typeof webLoginElements.find, 'undefined');\n    assert.strictEqual(typeof webLoginElements.click, 'undefined');\n\n    assert.strictEqual(webLoginElements instanceof Promise, false);\n    assert.strictEqual(typeof webLoginElements.then, 'function');\n    assert.strictEqual(typeof webLoginElements.nth, 'function');\n    assert.strictEqual(typeof webLoginElements.count, 'function');\n\n    const btnWEbElements = await webLoginElements;\n    assert.strictEqual(btnWEbElements.length, 2);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '5cc459b8-36a8-3042-8b4a-258883ea642b');\n  });\n\n  it('test .element.findElements()', async function() {\n    const webLoginElements = this.client.api.element.findElements('#weblogin');\n    assert.strictEqual(webLoginElements instanceof Element, false);\n    assert.strictEqual(typeof webLoginElements.find, 'undefined');\n    assert.strictEqual(typeof webLoginElements.click, 'undefined');\n\n    assert.strictEqual(webLoginElements instanceof Promise, false);\n    assert.strictEqual(typeof webLoginElements.then, 'function');\n    assert.strictEqual(typeof webLoginElements.nth, 'function');\n    assert.strictEqual(typeof webLoginElements.count, 'function');\n\n    const btnWEbElements = await webLoginElements;\n    assert.strictEqual(btnWEbElements.length, 2);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '5cc459b8-36a8-3042-8b4a-258883ea642b');\n  });\n\n  it('test .element().findAll().count()', async function() {\n    const resultPromise = this.client.api.element('#signupSection').findAll('.btn').count();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.value, 'object');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 3);\n\n    assert.strictEqual(await resultPromise.value, 3);\n    assert.strictEqual(await resultPromise.assert.equals(3), 3);\n    assert.strictEqual(await resultPromise.assert.not.equals(4), 3);\n  });\n\n  it('test .element().findAll().nth()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/2/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'span'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '9'}\n          ]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/2/property/role',\n        method: 'GET',\n        response: JSON.stringify({\n          value: 'button'\n        })\n      }, true);\n\n    const btnElement = this.client.api.element('#signupSection').findAll('.btn').nth(1);\n    assert.strictEqual(btnElement instanceof Element, false);\n    assert.strictEqual(btnElement instanceof Promise, true);\n    assert.strictEqual(typeof btnElement.find, 'function');\n    assert.strictEqual(typeof btnElement.getValue, 'function');\n\n    const btnWebElement = await btnElement;\n    assert.strictEqual(btnWebElement instanceof WebElement, true);\n    assert.strictEqual(await btnWebElement.getId(), '2');\n\n    const btnSpanElement = btnElement.find('span');\n    assert.strictEqual(await btnSpanElement.getId(), '9');\n\n    const btnElementProperty = await btnElement.getProperty('role');\n    assert.strictEqual(btnElementProperty, 'button');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindAllByAltText.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().findAllByAltText() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().findAllByAltText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '[alt=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').findAllByAltText('Email');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n\n    const resultCount = await resultPromise.count();\n    assert.strictEqual(resultCount, 3);\n\n    const secondResultPromise = resultPromise.nth(1);\n    assert.strictEqual(secondResultPromise instanceof Element, false);\n    assert.strictEqual(secondResultPromise instanceof Promise, true);\n    assert.strictEqual(typeof secondResultPromise.find, 'function');\n    assert.strictEqual(typeof secondResultPromise.getValue, 'function');\n\n    const secondResult = await secondResultPromise;\n    assert.strictEqual(secondResult instanceof WebElement, true);\n    assert.strictEqual(await secondResult.getId(), '2');\n  });\n\n  it('test .element().getAllByAltText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '[alt*=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getAllByAltText('Email', {exact: false});\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n  });\n\n  it('test .element.findAllByAltText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '[alt=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.findAllByAltText('Email');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindAllByPlaceholderText.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().findAllByPlaceholderText() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().findAllByPlaceholderText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '[placeholder=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').findAllByPlaceholderText('Email');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n\n    const resultCount = await resultPromise.count();\n    assert.strictEqual(resultCount, 3);\n\n    const secondResultPromise = resultPromise.nth(1);\n    assert.strictEqual(secondResultPromise instanceof Element, false);\n    assert.strictEqual(secondResultPromise instanceof Promise, true);\n    assert.strictEqual(typeof secondResultPromise.find, 'function');\n    assert.strictEqual(typeof secondResultPromise.getValue, 'function');\n\n    const secondResult = await secondResultPromise;\n    assert.strictEqual(secondResult instanceof WebElement, true);\n    assert.strictEqual(await secondResult.getId(), '2');\n  });\n\n  it('test .element().getAllByPlaceholderText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '[placeholder*=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getAllByPlaceholderText('Email', {exact: false});\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n  });\n\n  it('test .element.findAllByPlaceholderText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '[placeholder=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.findAllByPlaceholderText('Email');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindAllByRole.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().findAllByRole() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().findAllByRole()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '*[role~=\"button\"],input,summary,button'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').findAllByRole('button');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n\n    const resultCount = await resultPromise.count();\n    assert.strictEqual(resultCount, 3);\n\n    const secondResultPromise = resultPromise.nth(1);\n    assert.strictEqual(secondResultPromise instanceof Element, false);\n    assert.strictEqual(secondResultPromise instanceof Promise, true);\n    assert.strictEqual(typeof secondResultPromise.find, 'function');\n    assert.strictEqual(typeof secondResultPromise.getValue, 'function');\n\n    const secondResult = await secondResultPromise;\n    assert.strictEqual(secondResult instanceof WebElement, true);\n    assert.strictEqual(await secondResult.getId(), '2');\n  });\n\n  it('test .element().getAllByRole()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '*[role~=\"button\"],input,summary,button'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getAllByRole('button');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n  });\n\n  it('test .element.findAllByRole()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '*[role~=\"button\"],input,summary,button'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.findAllByRole('button');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindAllByText.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().findAllByText() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().findAllByText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'xpath',\n        value: './/*[text()=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').findAllByText('Email');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n\n    const resultCount = await resultPromise.count();\n    assert.strictEqual(resultCount, 3);\n\n    const secondResultPromise = resultPromise.nth(1);\n    assert.strictEqual(secondResultPromise instanceof Element, false);\n    assert.strictEqual(secondResultPromise instanceof Promise, true);\n    assert.strictEqual(typeof secondResultPromise.find, 'function');\n    assert.strictEqual(typeof secondResultPromise.getValue, 'function');\n\n    const secondResult = await secondResultPromise;\n    assert.strictEqual(secondResult instanceof WebElement, true);\n    assert.strictEqual(await secondResult.getId(), '2');\n  });\n\n  it('test .element().getAllByText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'xpath',\n        value: './/*[contains(text(),\"Email\")]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getAllByText('Email', {exact: false});\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n  });\n\n  it('test .element.findAllByText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'xpath',\n        value: './/*[text()=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '8'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'},\n          {'element-6066-11e4-a52e-4f735466cecf': '3'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.findAllByText('Email');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(typeof resultPromise.click, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.nth, 'function');\n    assert.strictEqual(typeof resultPromise.count, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result.length, 3);\n    assert.strictEqual(result[0] instanceof WebElement, true);\n    assert.strictEqual(await result[0].getId(), '8');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindByAltText.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('.findByAltText() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().findByAltText(exact)/getByAltText(exact)', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '[alt=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '7'}]\n      })\n    }, true, true);\n\n    const submitBtnElement = this.client.api.element('#signupSection').findByAltText('Email');\n    assert.strictEqual(submitBtnElement instanceof Element, true);\n    assert.strictEqual(await submitBtnElement.getId(), '7');\n    const submitBtnWebElement = await submitBtnElement;\n    assert.strictEqual(submitBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement.getId(), '7');\n\n    const submitBtnElement2 = this.client.api.element('#signupSection').getByAltText('Email');\n    assert.strictEqual(submitBtnElement2 instanceof Element, true);\n    assert.strictEqual(await submitBtnElement2.getId(), '7');\n    const submitBtnWebElement2 = await submitBtnElement2;\n    assert.strictEqual(submitBtnWebElement2 instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement2.getId(), '7');\n\n    await this.client.start();\n  });\n\n  it('test .element().findByAltText()/getByAltText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '[alt*=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '8'}]\n      })\n    }, true, true);\n\n    const submitBtnElement = this.client.api.element('#signupSection').findByAltText('Email', {exact: false});\n    assert.strictEqual(submitBtnElement instanceof Element, true);\n    assert.strictEqual(await submitBtnElement.getId(), '8');\n    const submitBtnWebElement = await submitBtnElement;\n    assert.strictEqual(submitBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement.getId(), '8');\n\n    const submitBtnElement2 = this.client.api.element('#signupSection').getByAltText('Email', {exact: false});\n    assert.strictEqual(submitBtnElement2 instanceof Element, true);\n    assert.strictEqual(await submitBtnElement2.getId(), '8');\n    const submitBtnWebElement2 = await submitBtnElement2;\n    assert.strictEqual(submitBtnWebElement2 instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement2.getId(), '8');\n\n    await this.client.start();\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindByLabelText.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('.findByLabelText() commands', function () {\n  beforeEach(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .findByLabelText() (findByForId)', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'xpath',\n          value: './/label[text()=\"Email\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '1'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        method: 'POST',\n        response: JSON.stringify({\n          value: 'email'\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[id=\"email\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '2'}]\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').findByLabelText('Email');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n    const id = await resultPromise.getId();\n    assert.strictEqual(id, '2');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '2');\n  });\n\n  it('test .getByLabelText(exact=false) (findByForId)', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'xpath',\n          value: './/label[contains(text(),\"Email\")]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '1'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        method: 'POST',\n        response: JSON.stringify({\n          value: 'email'\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[id=\"email\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '2'}]\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getByLabelText('Email', {exact: false});\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n    assert.strictEqual(await resultPromise.getId(), '2');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '2');\n  });\n\n  it('test .findByLabelText() (findByAriaLabelled)', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'xpath',\n          value: './/label[text()=\"Email\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '1'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        method: 'POST',\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        method: 'POST',\n        response: JSON.stringify({\n          value: 'email-label'\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[aria-labelledby=\"email-label\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '2'}]\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').findByLabelText('Email');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n    assert.strictEqual(await resultPromise.getId(), '2');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '2');\n  });\n  \n  it('test .findByLabelText() (findByDirectNesting)', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'xpath',\n          value: './/label[text()=\"Email\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '1'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        method: 'POST',\n        response: JSON.stringify({\n          value: null\n        })\n      }, true, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/1/element',\n        postdata: {\n          using: 'css selector',\n          value: 'input'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: {'element-6066-11e4-a52e-4f735466cecf': '2'}\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').findByLabelText('Email');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n    assert.strictEqual(await resultPromise.getId(), '2');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '2');\n  });\n\n  it('test .findByLabelText() (findByDeepNesting)', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'xpath',\n          value: './/label[text()=\"Email\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: []\n        }),\n        times: 3\n      })\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'xpath',\n          value: './/label[*[text()=\"Email\"]]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '1'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/1/element',\n        postdata: {\n          using: 'css selector',\n          value: 'input'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: {'element-6066-11e4-a52e-4f735466cecf': '2'}\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').findByLabelText('Email', {\n      timeout: 200,\n      retryInterval: 100\n    });\n\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n\n    const id = await resultPromise.getId();\n    assert.strictEqual(id, '2');\n    //\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '2');\n  });\n\n  it('test .findByLabelText() (aria-label)', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'xpath',\n          value: './/label[text()=\"Email\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: []\n        }),\n        times: 3\n      })\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'xpath',\n          value: './/label[*[text()=\"Email\"]]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: []\n        }),\n        times: 3\n      })\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[aria-label=\"Email\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '2'}]\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').findByLabelText('Email', {\n      timeout: 200,\n      retryInterval: 100\n    });\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n    assert.strictEqual(await resultPromise.getId(), '2');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '2');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindByPlaceholderText.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('.findByPlaceholderText() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().findByPlaceholderText(exact)/getByPlaceholderText(exact)', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '[placeholder=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '3'}]\n      })\n    }, true, true);\n\n    const submitBtnElement = this.client.api.element('#signupSection').findByPlaceholderText('Email');\n    assert.strictEqual(submitBtnElement instanceof Element, true);\n    assert.strictEqual(await submitBtnElement.getId(), '3');\n    const submitBtnWebElement = await submitBtnElement;\n    assert.strictEqual(submitBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement.getId(), '3');\n\n    const submitBtnElement2 = this.client.api.element('#signupSection').getByPlaceholderText('Email');\n    assert.strictEqual(submitBtnElement2 instanceof Element, true);\n    assert.strictEqual(await submitBtnElement2.getId(), '3');\n    const submitBtnWebElement2 = await submitBtnElement2;\n    assert.strictEqual(submitBtnWebElement2 instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement2.getId(), '3');\n\n    await this.client.start();\n  });\n\n  it('test .element().findByPlaceholderText()/getByPlaceholderText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '[placeholder*=\"Email\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '4'}]\n      })\n    }, true, true);\n\n    const submitBtnElement = this.client.api.element('#signupSection').findByPlaceholderText('Email', {exact: false});\n    assert.strictEqual(submitBtnElement instanceof Element, true);\n    assert.strictEqual(await submitBtnElement.getId(), '4');\n    const submitBtnWebElement = await submitBtnElement;\n    assert.strictEqual(submitBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement.getId(), '4');\n\n    const submitBtnElement2 = this.client.api.element('#signupSection').getByPlaceholderText('Email', {exact: false});\n    assert.strictEqual(submitBtnElement2 instanceof Element, true);\n    assert.strictEqual(await submitBtnElement2.getId(), '4');\n    const submitBtnWebElement2 = await submitBtnElement2;\n    assert.strictEqual(submitBtnWebElement2 instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement2.getId(), '4');\n\n    await this.client.start();\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindByRole.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().findByRole() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().findByRole()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '*[role~=\"button\"],input,summary,button'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '9'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').findByRole('button');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n  \n  it('test .element().getByRole()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'css selector',\n        value: '*[role~=\"button\"],input,summary,button'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '9'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getByRole('button');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element.findByRole()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '*[role~=\"button\"],input,summary,button'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [\n          {'element-6066-11e4-a52e-4f735466cecf': '9'},\n          {'element-6066-11e4-a52e-4f735466cecf': '2'}\n        ]\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.findByRole('button');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindByText.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('.findByText() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().findByText(exact)/getByText(exact)', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'xpath',\n        value: './/*[text()=\"Submit\"]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '5'}]\n      })\n    }, true, true);\n\n    const submitBtnElement = this.client.api.element('#signupSection').findByText('Submit');\n    assert.strictEqual(submitBtnElement instanceof Element, true);\n    assert.strictEqual(await submitBtnElement.getId(), '5');\n    const submitBtnWebElement = await submitBtnElement;\n    assert.strictEqual(submitBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement.getId(), '5');\n\n    const submitBtnElement2 = this.client.api.element('#signupSection').getByText('Submit');\n    assert.strictEqual(submitBtnElement2 instanceof Element, true);\n    assert.strictEqual(await submitBtnElement2.getId(), '5');\n    const submitBtnWebElement2 = await submitBtnElement2;\n    assert.strictEqual(submitBtnWebElement2 instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement2.getId(), '5');\n\n    await this.client.start();\n  });\n\n  it('test .element().findByText()/getByText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/elements',\n      postdata: {\n        using: 'xpath',\n        value: './/*[contains(text(),\"Submit\")]'\n      },\n      method: 'POST',\n      response: JSON.stringify({\n        value: [{'element-6066-11e4-a52e-4f735466cecf': '6'}]\n      })\n    }, true, true);\n\n    const submitBtnElement = this.client.api.element('#signupSection').findByText('Submit', {exact: false});\n    assert.strictEqual(submitBtnElement instanceof Element, true);\n    assert.strictEqual(await submitBtnElement.getId(), '6');\n    const submitBtnWebElement = await submitBtnElement;\n    assert.strictEqual(submitBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement.getId(), '6');\n\n    const submitBtnElement2 = this.client.api.element('#signupSection').getByText('Submit', {exact: false});\n    assert.strictEqual(submitBtnElement2 instanceof Element, true);\n    assert.strictEqual(await submitBtnElement2.getId(), '6');\n    const submitBtnWebElement2 = await submitBtnElement2;\n    assert.strictEqual(submitBtnWebElement2 instanceof WebElement, true);\n    assert.strictEqual(await submitBtnWebElement2.getId(), '6');\n\n    await this.client.start();\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testFindOnErrors.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst Mocks = require('../../../../lib/command-mocks.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst {settings} = common;\n\ndescribe('element().isPresent() command', function() {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element.find(suppressNotFoundErrors: true) suppresses NoSuchElementError', async function() {\n    Mocks.createNewW3CSession();\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      method: 'POST',\n      postdata: JSON.stringify({using: 'css selector', value: '#wrong'}),\n      response: JSON.stringify({\n        value: []\n      })\n    });\n\n    let globalReporterCalled = false;\n\n    const globals = {\n      reporter(results) {\n        globalReporterCalled = true;\n        if (Object.prototype.hasOwnProperty.call(results, 'lastError')) {\n          assert.notStrictEqual(results.lastError.name, 'NoSuchElementError');\n        }\n      },\n      waitForConditionTimeout: 100,\n      selector: '#wrong',\n      suppressNotFoundErrors: true\n    };\n    const testsPath = [\n      path.join(__dirname, '../../../../sampletests/webelement/findWithSuppressNotFoundErrors.js')\n    ];\n\n    await NightwatchClient.runTests(testsPath, settings({\n      globals,\n      output_folder: 'output',\n      selenium_host: null\n    }));\n\n    assert.strictEqual(globalReporterCalled, true);\n  });\n\n  it('test .element.find(suppressNotFoundErrors: false) does not suppress NoSuchElementError', async function() {\n    Mocks.createNewW3CSession();\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      method: 'POST',\n      postdata: JSON.stringify({using: 'css selector', value: '#wrong'}),\n      response: JSON.stringify({\n        value: []\n      })\n    });\n\n    let globalReporterCalled = false;\n\n    const globals = {\n      reporter(results) {\n        globalReporterCalled = true;\n        assert.strictEqual(results.lastError.name, 'NoSuchElementError');\n      },\n      waitForConditionTimeout: 100,\n      selector: '#wrong',\n      suppressNotFoundErrors: false\n    };\n    const testsPath = [\n      path.join(__dirname, '../../../../sampletests/webelement/findWithSuppressNotFoundErrors.js')\n    ];\n\n    await NightwatchClient.runTests(testsPath, settings({\n      globals,\n      output_folder: 'output',\n      selenium_host: null\n    }));\n\n    assert.strictEqual(globalReporterCalled, true);\n  });\n\n  it('test .element.find(suppressNotFoundErrors: true) does not suppress other errors', async function() {\n    Mocks.createNewW3CSession();\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      method: 'POST',\n      postdata: JSON.stringify({using: 'css selector', value: '@wrong'}),\n      response: {\n        value: {\n          error: 'invalid selector',\n          message: 'invalid selector',\n          stacktrace: ''\n        }\n      },\n      statusCode: 400\n    });\n\n    let globalReporterCalled = false;\n\n    const globals = {\n      reporter(results) {\n        globalReporterCalled = true;\n        assert.strictEqual(results.lastError.name, 'InvalidSelectorError');\n      },\n      waitForConditionTimeout: 100,\n      selector: '@wrong',\n      suppressNotFoundErrors: true\n    };\n    const testsPath = [\n      path.join(__dirname, '../../../../sampletests/webelement/findWithSuppressNotFoundErrors.js')\n    ];\n\n    await NightwatchClient.runTests(testsPath, settings({\n      globals,\n      output_folder: 'output',\n      selenium_host: null\n    }));\n\n    assert.strictEqual(globalReporterCalled, true);\n  });\n\n  it('test .element.find(suppressNotFoundErrors: false) does not suppress other errors', async function() {\n    Mocks.createNewW3CSession();\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      method: 'POST',\n      postdata: JSON.stringify({using: 'css selector', value: '@wrong'}),\n      response: {\n        value: {\n          error: 'invalid selector',\n          message: 'invalid selector',\n          stacktrace: ''\n        }\n      },\n      statusCode: 400\n    });\n\n    let globalReporterCalled = false;\n\n    const globals = {\n      reporter(results) {\n        globalReporterCalled = true;\n        assert.strictEqual(results.lastError.name, 'InvalidSelectorError');\n      },\n      waitForConditionTimeout: 100,\n      selector: '@wrong',\n      suppressNotFoundErrors: false\n    };\n    const testsPath = [\n      path.join(__dirname, '../../../../sampletests/webelement/findWithSuppressNotFoundErrors.js')\n    ];\n\n    await NightwatchClient.runTests(testsPath, settings({\n      globals,\n      output_folder: 'output',\n      selenium_host: null\n    }));\n\n    assert.strictEqual(globalReporterCalled, true);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetAccessibleName.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getAccessibleName() command', function () {\n  this.timeout(10000000);\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getAccessibleName()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/computedlabel',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Signup'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getAccessibleName();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.value, 'object');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'Signup');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'Signup');\n  });\n\n  it('test .element().accessibleName() alias', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/computedlabel',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Signup'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').accessibleName();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.value, 'object');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'Signup');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'Signup');\n  });\n\n  it('test .element().getComputedLabel() alias', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/computedlabel',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Signup'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getComputedLabel();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.value, 'object');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'Signup');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'Signup');\n  });\n\n  it('test .element().find().getAccessibleName()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/computedlabel',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Help'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getAccessibleName();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.value, 'object');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'Help');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'Help');\n  });\n\n  it('test .element.find().getAccessibleName()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/computedlabel',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Signup'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getAccessibleName();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.value, 'object');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'Signup');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'Signup');\n  });\n\n  it('test .element().getAccessibleName() assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/computedlabel',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Signup'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getAccessibleName();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n\n    assert.strictEqual(await resultPromise.assert.equals('Signup'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.contains('Sign'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.matches(/Si[a-z]{2}up/), 'Signup');\n\n    assert.strictEqual(await resultPromise.assert.not.equals('Signupx'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.not.contains('Signupx'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.not.matches(/Si[a-z]{2}upx/), 'Signup');\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetAriaRole.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getAriaRole() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getAriaRole()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/computedrole',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'signupSection'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getAriaRole();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'signupSection');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'signupSection');\n  });\n\n  it('test .element().ariaRole() alias', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/computedrole',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'signupSection'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').ariaRole();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'signupSection');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'signupSection');\n  });\n\n  it('test .element().getComputedRole() alias', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/computedrole',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'signupSection'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getComputedRole();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'signupSection');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'signupSection');\n  });\n\n  it('test .element().find().getAriaRole()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/computedrole',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'button'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getAriaRole();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'button');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'button');\n  });\n\n  it('test .element.find().getAriaRole()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/computedrole',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'signupSection'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getAriaRole();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'signupSection');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'signupSection');\n  });\n\n  it('test .element().getAriaRole() assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/computedrole',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'signupSection'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getAriaRole();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals('signupSection'), 'signupSection');\n    assert.strictEqual(await resultPromise.assert.contains('signup'), 'signupSection');\n    assert.strictEqual(await resultPromise.assert.matches(/si[a-z]{2}upS[a-z]{6}/), 'signupSection');\n\n    assert.strictEqual(await resultPromise.assert.not.equals('Signupx'), 'signupSection');\n    assert.strictEqual(await resultPromise.assert.not.contains('Signupx'), 'signupSection');\n    assert.strictEqual(await resultPromise.assert.not.matches(/Si[a-z]{2}upx/), 'signupSection');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetAttribute.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getAttribute() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getAttribute()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'text'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getAttribute('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'text');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'text');\n  });\n\n  it('test .element.attr() alias', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'text'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').attr('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'text');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'text');\n  });\n\n  it('test .element().attribute() alias', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'text'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').attribute('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'text');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'text');\n  });\n\n  it('test .element().find().getAttribute()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'text'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getAttribute('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'text');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'text');\n  });\n\n  it('test .element.find().getAttribute()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'text'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getAttribute('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'text');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'text');\n  });\n\n  it('test .element().getAttribute() assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'text'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getAttribute('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals('text'), 'text');\n    assert.strictEqual(await resultPromise.assert.contains('tex'), 'text');\n    assert.strictEqual(await resultPromise.assert.matches(/te[a-z]{2}/), 'text');\n\n    assert.strictEqual(await resultPromise.assert.not.equals('texxt'), 'text');\n    assert.strictEqual(await resultPromise.assert.not.contains('texx'), 'text');\n    assert.strictEqual(await resultPromise.assert.not.matches(/te[a-z]{2}x/), 'text');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetCssProperty.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getCssProperty() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getCssProperty()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/css/height',\n      method: 'GET',\n      response: JSON.stringify({\n        value: '150px'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getCssProperty('height');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    \n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, '150px');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, '150px');\n  });\n\n  it('test .element().css()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/css/height',\n      method: 'GET',\n      response: JSON.stringify({\n        value: '150px'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').css('height');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    \n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, '150px');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, '150px');\n  });\n\n  it('test .element().getCssValue() alias', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/css/height',\n      method: 'GET',\n      response: JSON.stringify({\n        value: '150px'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getCssValue('height');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    \n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, '150px');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, '150px');\n  });\n\n  it('test .element().find().getCssProperty()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/css/height',\n      method: 'GET',\n      response: JSON.stringify({\n        value: '34px'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getCssProperty('height');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, '34px');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, '34px');\n  });\n\n  it('test .element.find().getCssProperty()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/css/height',\n      method: 'GET',\n      response: JSON.stringify({\n        value: '150px'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getCssProperty('height');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, '150px');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, '150px');\n  });\n\n  it('test .element().getCssProperty() assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/css/height',\n      method: 'GET',\n      response: JSON.stringify({\n        value: '150px'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getCssProperty('height');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    \n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals('150px'), '150px');\n    assert.strictEqual(await resultPromise.assert.contains('150'), '150px');\n    assert.strictEqual(await resultPromise.assert.matches(/150[a-z]{2}/), '150px');\n\n    assert.strictEqual(await resultPromise.assert.not.equals('150x'), '150px');\n    assert.strictEqual(await resultPromise.assert.not.contains('150x'), '150px');\n    assert.strictEqual(await resultPromise.assert.not.matches(/150[a-z]{2}x/), '150px');\n  });\n  \n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetFirstElementChild.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getFirstElementChild() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getFirstElementChild()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '9'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getFirstElementChild();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element().find().getFirstElementChild()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '10'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getFirstElementChild('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '10');\n  });\n\n  it('test .element.find().getFirstElementChild()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '9'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getFirstElementChild('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetId.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getId() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getId()', async function() {\n    const resultPromise = this.client.api.element('#signupSection').getId();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, '0');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, '0');\n  });\n\n  it('test .element().find().getId()', async function() {\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getId();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, '1');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, '1');\n  });\n\n  it('test .element.find().getId()', async function() {\n    const resultPromise = this.client.api.element.find('#signupSection').getId();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, '0');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, '0');\n  });\n\n  it('test .element().getId() assert', async function() {\n    const resultPromise = this.client.api.element('#signupSection').getId();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals('0'), '0');\n    assert.strictEqual(await resultPromise.assert.contains('0'), '0');\n    assert.strictEqual(await resultPromise.assert.matches(/[0-9]{1}/), '0');\n\n    assert.strictEqual(await resultPromise.assert.not.equals('1'), '0');\n    assert.strictEqual(await resultPromise.assert.not.contains('1'), '0');\n    assert.strictEqual(await resultPromise.assert.not.matches(/[0-1]{2}x/), '0');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetLastElementChild.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getLastElementChild() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getLastElementChild()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '9'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getLastElementChild();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    // TODO: getLastElementChild() should return WebElement instead of JSON_WEB_OBJECT.\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element().find().getLastElementChild()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '10'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getLastElementChild('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '10');\n  });\n\n  it('test .element.find().getLastElementChild()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '9'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getLastElementChild('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetNextElementSibling.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getNextElementSibling() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getNextElementSibling()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '9'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getNextElementSibling();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element().find().getNextElementSibling()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '10'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getNextElementSibling('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '10');\n  });\n\n  it('test .element.find().getNextElementSibling()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '9'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getNextElementSibling('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetPreviousElementSibling.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getPreviousElementSibling() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getPreviousElementSibling()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '9'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getPreviousElementSibling();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element().find().getPreviousElementSibling()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '10'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getPreviousElementSibling('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '10');\n  });\n\n  it('test .element.find().getPreviousElementSibling()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '9'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getPreviousElementSibling('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetProperty.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getProperty() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getProperty()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/property/classList',\n      method: 'GET',\n      response: JSON.stringify({\n        value: ['.signup']\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getProperty('classList');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, ['.signup']);\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, ['.signup']);\n  });\n\n  it('test .element().property()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/property/classList',\n      method: 'GET',\n      response: JSON.stringify({\n        value: ['.signup']\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').property('classList');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, ['.signup']);\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, ['.signup']);\n  });\n\n  it('test .element().prop() alias', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/property/classList',\n      method: 'GET',\n      response: JSON.stringify({\n        value: ['.signup']\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').prop('classList');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, ['.signup']);\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, ['.signup']);\n  });\n  \n  it('test .element().find().getProperty()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/property/classList',\n      method: 'GET',\n      response: JSON.stringify({\n        value: ['.btn']\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getProperty('classList');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, ['.btn']);\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, ['.btn']);\n  });\n\n  it('test .element.find().getProperty()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/property/classList',\n      method: 'GET',\n      response: JSON.stringify({\n        value: ['.signup']\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getProperty('classList');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, ['.signup']);\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, ['.signup']);\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetRect.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getRect() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getRect()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {height: 34, width: 443, x: 356, y: 381.5}\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getRect();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, {height: 34, width: 443, x: 356, y: 381.5});\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, {height: 34, width: 443, x: 356, y: 381.5});\n  });\n\n  it('test .element().rect()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {height: 34, width: 443, x: 356, y: 381.5}\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').rect();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, {height: 34, width: 443, x: 356, y: 381.5});\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, {height: 34, width: 443, x: 356, y: 381.5});\n  });\n\n  it('test .element().getSize()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {height: 34, width: 443, x: 356, y: 381.5}\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getSize();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, {height: 34, width: 443, x: 356, y: 381.5});\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, {height: 34, width: 443, x: 356, y: 381.5});\n  });\n\n  it('test .element().getLocation()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {height: 34, width: 443, x: 356, y: 381.5}\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getLocation();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, {height: 34, width: 443, x: 356, y: 381.5});\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, {height: 34, width: 443, x: 356, y: 381.5});\n  });\n\n  it('test .element().find().getRect()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {height: 34, width: 443, x: 356, y: 381.5}\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getRect();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, {height: 34, width: 443, x: 356, y: 381.5});\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, {height: 34, width: 443, x: 356, y: 381.5});\n  });\n\n  it('test .element.find().getRect()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {height: 34, width: 443, x: 356, y: 381.5}\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getRect();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.deepStrictEqual(result, {height: 34, width: 443, x: 356, y: 381.5});\n\n    const resultValue = await resultPromise.value;\n    assert.deepStrictEqual(resultValue, {height: 34, width: 443, x: 356, y: 381.5});\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetShadowRoot.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst {ShadowRoot} = require('selenium-webdriver/lib/webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getShadowRoot() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getShadowRoot()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/shadow',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {\n          'shadow-6066-11e4-a52e-4f735466cecf': '9'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.ok(result instanceof ShadowRoot);\n    assert.strictEqual(result.getId(), '9');\n  });\n\n  it('test .element().find().getShadowRoot()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/shadow',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {\n          'shadow-6066-11e4-a52e-4f735466cecf': '10'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getShadowRoot('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.ok(result instanceof ShadowRoot);\n    assert.strictEqual(result.getId(), '10');\n  });\n\n  it('test .element.find().getShadowRoot()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/shadow',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {\n          'shadow-6066-11e4-a52e-4f735466cecf': '9'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getShadowRoot('type');\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(resultPromise instanceof Promise, true);\n    assert.strictEqual(typeof resultPromise.find, 'function');\n    assert.strictEqual(typeof resultPromise.getValue, 'function');\n\n    const result = await resultPromise;\n    assert.ok(result instanceof ShadowRoot);\n    assert.strictEqual(result.getId(), '9');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetTagName.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getTagName() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getTagName()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/name',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'div'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getTagName();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'div');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'div');\n  });\n\n  it('test .element().tagName() alias', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/name',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'div'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').tagName();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'div');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'div');\n  });\n\n  it('test .element().find().getTagName()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/name',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'button'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getTagName();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'button');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'button');\n  });\n\n  it('test .element.find().getTagName()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/name',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'div'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getTagName();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'div');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'div');\n  });\n\n  it('test .element().getTagName() assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/name',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'div'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getTagName();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals('div'), 'div');\n    assert.strictEqual(await resultPromise.assert.contains('di'), 'div');\n    assert.strictEqual(await resultPromise.assert.matches(/di[a-z]{1}/), 'div');\n\n    assert.strictEqual(await resultPromise.assert.not.equals('divx'), 'div');\n    assert.strictEqual(await resultPromise.assert.not.contains('dx'), 'div');\n    assert.strictEqual(await resultPromise.assert.not.matches(/di[a-z]{2}x/), 'div');\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetText.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getText() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/text',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Signup'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getText();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'Signup');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'Signup');\n  });\n\n  it('test .element().text() alias', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/text',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Signup'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').text();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'Signup');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'Signup');\n  });\n\n  it('test .element().find().getText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/text',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Help'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getText();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'Help');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'Help');\n  });\n\n  it('test .element.find().getText()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/text',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Signup'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getText();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'Signup');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'Signup');\n  });\n\n  it('test .element().getText() assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/text',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Signup'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getText();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals('Signup'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.contains('Sign'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.matches(/Si[a-z]{2}up/), 'Signup');\n\n    assert.strictEqual(await resultPromise.assert.not.equals('Signupx'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.not.contains('Signupx'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.not.matches(/Si[a-z]{2}upx/), 'Signup');\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testGetValue.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().getValue() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().getValue()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/property/value',\n      method: 'GET',\n      response: JSON.stringify({\n        value: ''\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getValue();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, '');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, '');\n  });\n\n  it('test .element().find().getValue()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/property/value',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Help'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').getValue();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'Help');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'Help');\n  });\n\n  it('test .element.find().getValue()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/property/value',\n      method: 'GET',\n      response: JSON.stringify({\n        value: ''\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').getValue();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, '');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, '');\n  });\n\n  it('test .element().getValue() assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/property/value',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'Signup'\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').getValue();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals('Signup'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.contains('Sign'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.matches(/Si[a-z]{2}up/), 'Signup');\n\n    assert.strictEqual(await resultPromise.assert.not.equals('Signupx'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.not.contains('Signupx'), 'Signup');\n    assert.strictEqual(await resultPromise.assert.not.matches(/Si[a-z]{2}upx/), 'Signup');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testIsActive.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().isActive() command', function() {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().isActive() active', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/active',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '0'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isActive();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n  });\n\n  it('test .element().isActive() not active', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/active',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': 'random-elem'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isActive();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n  });\n\n  it('test .element().find().isActive()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/active',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '1'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').isActive();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n  });\n\n  it('test .element.find().isActive() not active', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/active',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': 'random-elem'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').isActive();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n  });\n\n  it('test .element().isActive() assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/active',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '0'\n        }\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isActive();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals(true), true);\n    assert.strictEqual(await resultPromise.assert.not.equals(false), true);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testIsEnabled.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().isEnabled() command', function() {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().isEnabled() enabled', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/enabled',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isEnabled();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n\n  });\n\n  it('test .element().isEnabled() not enabled', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/enabled',\n      method: 'GET',\n      response: JSON.stringify({\n        value: false\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isEnabled();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n  });\n\n  it('test .element().find().isEnabled()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/enabled',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').isEnabled();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n  });\n\n  it('test .element.find().isEnabled() not enabled', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/enabled',\n      method: 'GET',\n      response: JSON.stringify({\n        value: false\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').isEnabled();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n  });\n\n  it('test .element().isEnabled() assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/enabled',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isEnabled();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals(true), true);\n    assert.strictEqual(await resultPromise.assert.not.equals(false), true);\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testIsPresent.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst path = require('path');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\nconst NightwatchClient = common.require('index.js');\nconst {settings} = common;\n\ndescribe('element().isPresent() command', function() {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().isPresent() present', async function() {\n    const resultPromise = this.client.api.element('#signupSection').isPresent();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n\n  });\n\n  it('test .element().isPresent() not present', async function() {\n    const resultPromise = this.client.api.element('#wrong').isPresent();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n\n  });\n\n  it('test .element().find().isPresent() present', async function() {\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').isPresent();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n  });\n\n  it('test .element().find().isPresent() not present', async function() {\n    const resultPromise = this.client.api.element('#signupSection').find('#wrong').isPresent();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n  });\n\n  it('test .element().isPresent() suppresses NoSuchElementError', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      method: 'POST',\n      postdata: JSON.stringify({using: 'css selector', value: '#wrong'}),\n      response: JSON.stringify({\n        value: []\n      })\n    });\n\n    let globalReporterCalled = false;\n\n    const globals = {\n      reporter(results) {\n        globalReporterCalled = true;\n        if (Object.prototype.hasOwnProperty.call(results, 'lastError')) {\n          assert.notStrictEqual(results.lastError.name, 'NoSuchElementError');\n        }\n      },\n      waitForConditionTimeout: 100\n    };\n    const testsPath = [\n      path.join(__dirname, '../../../../sampletests/isPresent/elementNotPresent.js')\n    ];\n\n    await NightwatchClient.runTests(testsPath, settings({\n      globals,\n      output_folder: 'output',\n      selenium_host: null\n    }));\n\n    assert.strictEqual(globalReporterCalled, true);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testIsSelected.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().isSelected() command', function() {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().isSelected() selected', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isSelected();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n\n  });\n\n  it('test .element().isSelected() not selected', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: false\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isSelected();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n  });\n\n  it('test .element().find().isSelected()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').isSelected();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n  });\n\n  it('test .element.find().isSelected() not selected', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: false\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').isSelected();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n  });\n\n  it('test .element().isSelected() assert', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isSelected();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals(true), true);\n    assert.strictEqual(await resultPromise.assert.not.equals(false), true);\n  });\n\n});\n\n"
  },
  {
    "path": "test/src/api/commands/web-element/testIsVisible.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().isVisible() command', function() {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().isVisible() displayed', async function() {\n    let elementId;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      }),\n      onRequest(_, requestData) {\n        elementId = requestData.args[0]['element-6066-11e4-a52e-4f735466cecf'];\n      }\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isVisible();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(elementId, '0');\n  });\n\n  it('test .element().isDisplayed() displayed', async function() {\n    let elementId;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      }),\n      onRequest(_, requestData) {\n        elementId = requestData.args[0]['element-6066-11e4-a52e-4f735466cecf'];\n      }\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isDisplayed();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(elementId, '0');\n  });\n\n  it('test .element().isVisible() not displayed', async function() {\n    let elementId;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: false\n      }),\n      onRequest(_, requestData) {\n        elementId = requestData.args[0]['element-6066-11e4-a52e-4f735466cecf'];\n      }\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isVisible();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n    assert.strictEqual(elementId, '0');\n  });\n\n  it('test .element().isDisplayed() not displayed', async function() {\n    let elementId;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: false\n      }),\n      onRequest(_, requestData) {\n        elementId = requestData.args[0]['element-6066-11e4-a52e-4f735466cecf'];\n      }\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isDisplayed();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n    assert.strictEqual(elementId, '0');\n  });\n\n  it('test .element().find().isVisible()', async function() {\n    let elementId;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      }),\n      onRequest(_, requestData) {\n        elementId = requestData.args[0]['element-6066-11e4-a52e-4f735466cecf'];\n      }\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').isVisible();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(elementId, '1');\n  });\n\n  it('test .element.find().isVisible() not displayed', async function() {\n    let elementId;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: false\n      }),\n      onRequest(_, requestData) {\n        elementId = requestData.args[0]['element-6066-11e4-a52e-4f735466cecf'];\n      }\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').isVisible();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, false);\n    assert.strictEqual(elementId, '0');\n  });\n\n  it('test .element().isVisible() assert', async function() {\n    let elementId;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      }),\n      onRequest(_, requestData) {\n        elementId = requestData.args[0]['element-6066-11e4-a52e-4f735466cecf'];\n      }\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').isVisible();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    assert.strictEqual(await resultPromise.assert.equals(true), true);\n    assert.strictEqual(await resultPromise.assert.not.equals(false), true);\n    assert.strictEqual(elementId, '0');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testMoveTo.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().moveTo() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().moveTo()', async function() {\n    let moveToArgs;\n    this.client.transport.Actions.session.moveTo = function(args) {\n      moveToArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element('#signupSection').moveTo();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await moveToArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n    assert.strictEqual(moveToArgs.args[1], 0);\n    assert.strictEqual(moveToArgs.args[2], 0);\n  });\n\n  it('test .element().moveTo(x, y)', async function() {\n    let moveToArgs;\n    this.client.transport.Actions.session.moveTo = function(args) {\n      moveToArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element('#signupSection').moveTo(50, 100);\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await moveToArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n    assert.strictEqual(moveToArgs.args[1], 50);\n    assert.strictEqual(moveToArgs.args[2], 100);\n  });\n\n  it('test .element().find().moveTo()', async function() {\n    let moveToArgs;\n    this.client.transport.Actions.session.moveTo = function(args) {\n      moveToArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').moveTo();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '1');\n\n    const webElementArg = await moveToArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '1');\n    assert.strictEqual(moveToArgs.args[1], 0);\n    assert.strictEqual(moveToArgs.args[2], 0);\n  });\n\n  it('test .element.find().moveTo()', async function() {\n    let moveToArgs;\n    this.client.transport.Actions.session.moveTo = function(args) {\n      moveToArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element.find('#signupSection').moveTo();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await moveToArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n    assert.strictEqual(moveToArgs.args[1], 0);\n    assert.strictEqual(moveToArgs.args[2], 0);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testRightClick.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().rightClick() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().rightClick()', async function() {\n    let contextClickArgs;\n    this.client.transport.Actions.session.contextClick = function(args) {\n      contextClickArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element('#signupSection').rightClick();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await contextClickArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n  });\n\n  it('test .element().find().rightClick()', async function() {\n    let contextClickArgs;\n    this.client.transport.Actions.session.contextClick = function(args) {\n      contextClickArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').rightClick();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '1');\n\n    const webElementArg = await contextClickArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '1');\n  });\n\n  it('test .element.find().rightClick()', async function() {\n    let contextClickArgs;\n    this.client.transport.Actions.session.contextClick = function(args) {\n      contextClickArgs = args;\n\n      return Promise.resolve({\n        status: 0,\n        value: null\n      });\n    };\n\n    const resultPromise = this.client.api.element.find('#signupSection').rightClick();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n\n    const webElementArg = await contextClickArgs.args[0];\n    assert.deepStrictEqual(await webElementArg.getId(), '0');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testSendKeys.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().sendKeys() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().sendKeys()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[name=q]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: 'nightwatch',\n          value: [\n            'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('input[name=q]').sendKeys('nightwatch');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element().find().sendKeys()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[name=q]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: 'nightwatch',\n          value: [\n            'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('input[name=q]').sendKeys('night', 'watch');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element.find().sendKeys()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[name=q]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: 'nightwatch',\n          value: [\n            'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').find('input[name=q]').sendKeys(['night', 'watch']);\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testSetAttribute.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().setAttribute() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().setAttribute()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').setAttribute('some-name', 'some-value');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().find().setAttribute()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').setAttribute('some-name', 'some-value');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '1');\n  });\n\n  it('test .element.find().setAttribute()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').setAttribute('some-name', 'some-value');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testSetProperty.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().setProperty() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().setProperty()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').setProperty('some-name', 'some-value');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().find().setProperty()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').setProperty('some-name', 'some-value');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '1');\n  });\n\n  it('test .element.find().setProperty()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').setProperty('some-name', 'some-value');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testSetValue.js",
    "content": "const assert = require('assert');\nconst {WebElement, Key} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().setValue() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().setValue()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[name=q]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/clear',\n        method: 'POST',\n        postdata: {},\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: 'nightwatch',\n          value: [\n            'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('input[name=q]').setValue('nightwatch');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element().find().setValue()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[name=q]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/clear',\n        method: 'POST',\n        postdata: {},\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: 'nightwatch',\n          value: [\n            'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('input[name=q]').setValue('night', 'watch');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element.find().setValue()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[name=q]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/clear',\n        method: 'POST',\n        postdata: {},\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: 'nightwatch',\n          value: [\n            'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').find('input[name=q]').setValue(['night', 'watch']);\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element().setValue() with clear fallback sending keys', async function() {\n    let sendKeysMockCalled = 0;\n\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[name=q]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/clear',\n        method: 'POST',\n        postdata: {},\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/property/value',\n        method: 'GET',\n        response: {value: 'sample'}\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        response: {value: null},\n        onRequest(_, requestData) {\n          assert.strictEqual(requestData.text, Array(6).fill(Key.BACK_SPACE).join(''));\n          sendKeysMockCalled++;\n        }\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: 'nightwatch',\n          value: [\n            'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        }),\n        onRequest(_, requestData) {\n          assert.strictEqual(requestData.text, 'nightwatch');\n          sendKeysMockCalled++;\n        }\n      }, true);\n\n    const resultPromise = this.client.api.element('input[name=q]').setValue('nightwatch');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n\n    assert.strictEqual(sendKeysMockCalled, 2);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testShadowFind.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst {ShadowRoot} = require('selenium-webdriver/lib/webdriver.js');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().shadow().find() commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().shadow().find()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#helpBtn'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '5'}]\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(await shadowRootEl instanceof ShadowRoot, true);\n    assert.strictEqual(await shadowRootEl.getId(), '9');\n    \n    const helpBtnElement = shadowRootEl.find('#helpBtn');\n    assert.strictEqual(helpBtnElement instanceof Element, true);\n    assert.strictEqual(await helpBtnElement.getId(), '5');\n\n    const helpBtnWebElement = await helpBtnElement;\n    assert.strictEqual(helpBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await helpBtnWebElement.getId(), '5');\n  });\n\n  it('test .element().shadow().get()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#helpBtn'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '5'}]\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(await shadowRootEl instanceof ShadowRoot, true);\n    assert.strictEqual(await shadowRootEl.getId(), '9');\n    \n    const helpBtnElement = shadowRootEl.get('#helpBtn');\n    assert.strictEqual(helpBtnElement instanceof Element, true);\n    assert.strictEqual(await helpBtnElement.getId(), '5');\n\n    const helpBtnWebElement = await helpBtnElement;\n    assert.strictEqual(helpBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await helpBtnWebElement.getId(), '5');\n  });\n\n  it('test .element().shadow().findElement()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#helpBtn'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '5'}]\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(await shadowRootEl instanceof ShadowRoot, true);\n    assert.strictEqual(await shadowRootEl.getId(), '9');\n    \n    const helpBtnElement = shadowRootEl.findElement('#helpBtn');\n    assert.strictEqual(helpBtnElement instanceof Element, true);\n    assert.strictEqual(await helpBtnElement.getId(), '5');\n\n    const helpBtnWebElement = await helpBtnElement;\n    assert.strictEqual(helpBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await helpBtnWebElement.getId(), '5');\n  });\n\n  it('test .element().shadow().find(selectorObject)', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'xpath',\n          value: '//*[id=\"helpBtn\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '2'}]\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(await shadowRootEl instanceof ShadowRoot, true);\n    assert.strictEqual(await shadowRootEl.getId(), '9');\n    \n    const helpBtnElement = shadowRootEl.find({\n      locateStrategy: 'xpath', selector: '//*[id=\"helpBtn\"]'});\n    assert.strictEqual(helpBtnElement instanceof Element, true);\n    assert.strictEqual(await helpBtnElement.getId(), '2');\n\n    const helpBtnWebElement = await helpBtnElement;\n    assert.strictEqual(helpBtnWebElement instanceof WebElement, true);\n    assert.strictEqual(await helpBtnWebElement.getId(), '2');\n  });\n\n  it('test .element().shadow().find().getText()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#helpBtn'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '55'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/55/text',\n        method: 'GET',\n        response: JSON.stringify({\n          value: 'Help'\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    const helpBtnElement = shadowRootEl.find('#helpBtn');\n    const helpBtnTextPromise = helpBtnElement.getText();\n\n    assert.strictEqual(typeof helpBtnTextPromise.then, 'function');\n    assert.strictEqual(await helpBtnTextPromise, 'Help');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testShadowFindAll.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst {ShadowRoot} = require('selenium-webdriver/lib/webdriver.js');\nconst MockServer = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().shadow().findAll() commands', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().shadow().findAll()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'css selector',\n          value: '.btn'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '5'},\n            {'element-6066-11e4-a52e-4f735466cecf': '6'},\n            {'element-6066-11e4-a52e-4f735466cecf': '7'}\n          ]\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(await shadowRootEl instanceof ShadowRoot, true);\n    assert.strictEqual(await shadowRootEl.getId(), '9');\n\n    const btnElements = shadowRootEl.findAll('.btn');\n    assert.strictEqual(btnElements instanceof Element, false);\n    assert.strictEqual(typeof btnElements.find, 'undefined');\n    assert.strictEqual(typeof btnElements.click, 'undefined');\n\n    assert.strictEqual(btnElements instanceof Promise, false);\n    assert.strictEqual(typeof btnElements.then, 'function');\n    assert.strictEqual(typeof btnElements.nth, 'function');\n    assert.strictEqual(typeof btnElements.count, 'function');\n\n    const btnWEbElements = await btnElements;\n    assert.strictEqual(btnWEbElements.length, 3);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '5');\n    assert.strictEqual(await btnElements.nth(0).getId(), '5');\n  });\n\n  it('test .element().shadow().getAll()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'css selector',\n          value: '.btn'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '5'},\n            {'element-6066-11e4-a52e-4f735466cecf': '6'},\n            {'element-6066-11e4-a52e-4f735466cecf': '7'}\n          ]\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(await shadowRootEl instanceof ShadowRoot, true);\n    assert.strictEqual(await shadowRootEl.getId(), '9');\n\n    const btnElements = shadowRootEl.getAll('.btn');\n    assert.strictEqual(btnElements instanceof Element, false);\n    assert.strictEqual(typeof btnElements.find, 'undefined');\n    assert.strictEqual(typeof btnElements.click, 'undefined');\n\n    assert.strictEqual(btnElements instanceof Promise, false);\n    assert.strictEqual(typeof btnElements.then, 'function');\n    assert.strictEqual(typeof btnElements.nth, 'function');\n    assert.strictEqual(typeof btnElements.count, 'function');\n\n    const btnWEbElements = await btnElements;\n    assert.strictEqual(btnWEbElements.length, 3);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '5');\n    assert.strictEqual(await btnElements.nth(0).getId(), '5');\n  });\n\n  it('test .element().shadow().findElements()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'css selector',\n          value: '.btn'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '5'},\n            {'element-6066-11e4-a52e-4f735466cecf': '6'},\n            {'element-6066-11e4-a52e-4f735466cecf': '7'}\n          ]\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(await shadowRootEl instanceof ShadowRoot, true);\n    assert.strictEqual(await shadowRootEl.getId(), '9');\n\n    const btnElements = shadowRootEl.findElements('.btn');\n    assert.strictEqual(btnElements instanceof Element, false);\n    assert.strictEqual(typeof btnElements.find, 'undefined');\n    assert.strictEqual(typeof btnElements.click, 'undefined');\n\n    assert.strictEqual(btnElements instanceof Promise, false);\n    assert.strictEqual(typeof btnElements.then, 'function');\n    assert.strictEqual(typeof btnElements.nth, 'function');\n    assert.strictEqual(typeof btnElements.count, 'function');\n\n    const btnWEbElements = await btnElements;\n    assert.strictEqual(btnWEbElements.length, 3);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '5');\n    assert.strictEqual(await btnElements.nth(0).getId(), '5');\n  });\n\n  it('test .element().shadow().findAll(selectorObject)', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'xpath',\n          value: '//*[id=\"helpBtn\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '4'},\n            {'element-6066-11e4-a52e-4f735466cecf': '5'}\n          ]\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(await shadowRootEl instanceof ShadowRoot, true);\n    assert.strictEqual(await shadowRootEl.getId(), '9');\n\n    const helpBtnElements = shadowRootEl.findAll({\n      locateStrategy: 'xpath', selector: '//*[id=\"helpBtn\"]'\n    });\n    assert.strictEqual(helpBtnElements instanceof Element, false);\n    assert.strictEqual(typeof helpBtnElements.find, 'undefined');\n    assert.strictEqual(typeof helpBtnElements.click, 'undefined');\n\n    assert.strictEqual(helpBtnElements instanceof Promise, false);\n    assert.strictEqual(typeof helpBtnElements.then, 'function');\n    assert.strictEqual(typeof helpBtnElements.nth, 'function');\n    assert.strictEqual(typeof helpBtnElements.count, 'function');\n\n    const btnWEbElements = await helpBtnElements;\n    assert.strictEqual(btnWEbElements.length, 2);\n    assert.strictEqual(btnWEbElements[0] instanceof WebElement, true);\n    assert.strictEqual(await btnWEbElements[0].getId(), '4');\n    assert.strictEqual(await helpBtnElements.nth(0).getId(), '4');\n  });\n\n  it('test .element().shadow().findAll().count()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'css selector',\n          value: '.btn'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '5'},\n            {'element-6066-11e4-a52e-4f735466cecf': '6'},\n            {'element-6066-11e4-a52e-4f735466cecf': '7'}\n          ]\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(await shadowRootEl instanceof ShadowRoot, true);\n    assert.strictEqual(await shadowRootEl.getId(), '9');\n\n    const resultPromise = shadowRootEl.findAll('.btn').count();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n    assert.strictEqual(typeof resultPromise.value, 'object');\n    assert.strictEqual(typeof resultPromise.assert, 'object');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 3);\n\n    assert.strictEqual(await resultPromise.value, 3);\n    assert.strictEqual(await resultPromise.assert.equals(3), 3);\n    assert.strictEqual(await resultPromise.assert.not.equals(4), 3);\n  });\n\n  it('test .element().findAll().nth()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/shadow',\n        method: 'GET',\n        response: JSON.stringify({\n          value: {'shadow-6066-11e4-a52e-4f735466cecf': '9'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/shadow/9/elements',\n        postdata: {\n          using: 'css selector',\n          value: '.btn'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '5'},\n            {'element-6066-11e4-a52e-4f735466cecf': '6'},\n            {'element-6066-11e4-a52e-4f735466cecf': '7'}\n          ]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/6/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'span'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '9'}\n          ]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/6/property/role',\n        method: 'GET',\n        response: JSON.stringify({\n          value: 'button'\n        })\n      }, true);\n\n    const shadowRootEl = this.client.api.element('#signupSection').getShadowRoot();\n    assert.strictEqual(await shadowRootEl instanceof ShadowRoot, true);\n    assert.strictEqual(await shadowRootEl.getId(), '9');\n\n    const btnElement = shadowRootEl.findAll('.btn').nth(1);\n    assert.strictEqual(btnElement instanceof Element, false);\n    assert.strictEqual(btnElement instanceof Promise, true);\n    assert.strictEqual(typeof btnElement.find, 'function');\n    assert.strictEqual(typeof btnElement.getValue, 'function');\n\n    const btnWebElement = await btnElement;\n    assert.strictEqual(btnWebElement instanceof WebElement, true);\n    assert.strictEqual(await btnWebElement.getId(), '6');\n\n    const btnSpanElement = btnElement.find('span');\n    assert.strictEqual(await btnSpanElement.getId(), '9');\n\n    const btnElementProperty = await btnElement.getProperty('role');\n    assert.strictEqual(btnElementProperty, 'button');\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/commands/web-element/testSubmit.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().submit() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().submit()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').submit();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().find().submit()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').submit();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '1');\n  });\n\n  it('test .element.find().submit()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').submit();\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testTakeScreenshot.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().takeScreenshot() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().takeScreenshot()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'iVBORw0KGgoAAAANSUhEUgAAAbsAAAAiCAYAAADGd3chAAABK',\n        suppressBase64Data: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').takeScreenshot();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'iVBORw0KGgoAAAANSUhEUgAAAbsAAAAiCAYAAADGd3chAAABK');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'iVBORw0KGgoAAAANSUhEUgAAAbsAAAAiCAYAAADGd3chAAABK');\n  });\n\n  it('test .element().find().takeScreenshot()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/1/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'iVBORw0KGgoAAAANSUhEUgAAAbsAAAAiCAYAAADGd3chAAABK',\n        suppressBase64Data: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').takeScreenshot();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'iVBORw0KGgoAAAANSUhEUgAAAbsAAAAiCAYAAADGd3chAAABK');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'iVBORw0KGgoAAAANSUhEUgAAAbsAAAAiCAYAAADGd3chAAABK');\n  });\n\n  it('test .element.find().takeScreenshot()', async function() {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'iVBORw0KGgoAAAANSUhEUgAAAbsAAAAiCAYAAADGd3chAAABK',\n        suppressBase64Data: true\n      })\n    }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').takeScreenshot();\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n\n    assert.strictEqual(resultPromise instanceof Promise, false);\n    assert.strictEqual(typeof resultPromise.then, 'function');\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, false);\n    assert.strictEqual(result, 'iVBORw0KGgoAAAANSUhEUgAAAbsAAAAiCAYAAADGd3chAAABK');\n\n    const resultValue = await resultPromise.value;\n    assert.strictEqual(resultValue, 'iVBORw0KGgoAAAANSUhEUgAAAbsAAAAiCAYAAADGd3chAAABK');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testUncheck.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().uncheck() command', function() {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().uncheck() will uncheck checkbox if selected', async function () {\n    let nCallsToClick = 0;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      }),\n      onRequest(_) {\n        nCallsToClick++;\n      }\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    // For returning 'checkbox' from getAttribute for type attribute\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'checkbox'\n      })\n    }, true);\n\n    const resultPromise = await this.client.api.element('#signupSection').uncheck();\n\n    // Click command should have been used one time to uncheck\n    assert.strictEqual(nCallsToClick, 1);\n\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().uncheck() will uncheck radio input if selected', async function () {\n    let nCallsToClick = 0;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      }),\n      onRequest(_) {\n        nCallsToClick++;\n      }\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    // For returning 'radio' from getAttribute for type attribute\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'radio'\n      })\n    }, true);\n\n    const resultPromise = await this.client.api.element('#signupSection').uncheck();\n\n    // Click command should have been used one time to uncheck\n    assert.strictEqual(nCallsToClick, 1);\n\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().uncheck() will not uncheck if not a checkbox', async function () {\n    let nCallsToClick = 0;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      }),\n      onRequest(_) {\n        nCallsToClick++;\n      }\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: true\n      })\n    }, true);\n\n    // For returning 'submit' from getAttribute for type attribute\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'submit'\n      })\n    }, true);\n\n    const resultPromise = await this.client.api.element('#signupSection').uncheck();\n\n    // Click command should not have been fired\n    assert.strictEqual(nCallsToClick, 0);\n\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n\n  it('test .element().uncheck() will not click if unchecked already', async function () {\n    let nCallsToClick = 0;\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/click',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      }),\n      onRequest(_) {\n        nCallsToClick++;\n      }\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/0/selected',\n      method: 'GET',\n      response: JSON.stringify({\n        value: false\n      })\n    }, true);\n\n    // For returning 'checkbox' from getAttribute for type attribute\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST',\n      response: JSON.stringify({\n        value: 'checkbox'\n      })\n    }, true);\n\n    const resultPromise = await this.client.api.element('#signupSection').uncheck();\n\n    // Click command should not have been executed since element is unchecked already\n    assert.strictEqual(nCallsToClick, 0);\n    \n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '0');\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/commands/web-element/testUpdate.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().update() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().update()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[name=q]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/clear',\n        method: 'POST',\n        postdata: {},\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: 'nightwatch',\n          value: [\n            'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('input[name=q]').update('nightwatch');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element().find().update()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[name=q]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/clear',\n        method: 'POST',\n        postdata: {},\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: 'nightwatch',\n          value: [\n            'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('input[name=q]').update('night', 'watch');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element.find().update()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: 'input[name=q]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/clear',\n        method: 'POST',\n        postdata: {},\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: 'nightwatch',\n          value: [\n            'n', 'i', 'g', 'h', 't', 'w', 'a', 't', 'c', 'h'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').find('input[name=q]').update(['night', 'watch']);\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/web-element/testUpload.js",
    "content": "const assert = require('assert');\nconst {WebElement} = require('selenium-webdriver');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\nconst common = require('../../../../common.js');\nconst Element = common.require('element/index.js');\n\ndescribe('element().upload() command', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .element().upload()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#choosefile'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: '/file.js',\n          value: [\n            '/', 'f', 'i', 'l', 'e', '.', 'j', 's'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#choosefile').upload('/file.js');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element().find().upload()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#choosefile'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: '/file.js',\n          value: [\n            '/', 'f', 'i', 'l', 'e', '.', 'j', 's'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element('#signupSection').find('#choosefile').upload('/file.js');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n\n  it('test .element.find().upload()', async function() {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#choosefile'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '9'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/9/value',\n        method: 'POST',\n        postdata: {\n          text: '/file.js',\n          value: [\n            '/', 'f', 'i', 'l', 'e', '.', 'j', 's'\n          ]\n        },\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    const resultPromise = this.client.api.element.find('#signupSection').find('#choosefile').upload('/file.js');\n    // neither an instance of Element or Promise, but an instance of ScopedWebElement.\n    assert.strictEqual(resultPromise instanceof Element, false);\n    assert.strictEqual(typeof resultPromise.find, 'undefined');\n    assert.strictEqual(resultPromise instanceof Promise, false);\n\n    const result = await resultPromise;\n    assert.strictEqual(result instanceof WebElement, true);\n    assert.strictEqual(await result.getId(), '9');\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/window/testCloseWindow.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('closeWindow', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.closeWindow() success', function(done) {\n    const api = this.client.api;\n    this.client.api.closeWindow(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/window/testMaximizeWindow.js",
    "content": "const assert = require('assert');\nconst Mocks = require('../../../../lib/command-mocks.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\n\ndescribe('maximizeWindow', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.maximizeWindow()', function(done) {\n    Mocks.maximizeWindow();\n    this.client.api.maximizeWindow(function callback(result) {\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/window/testWindowCommands.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands.js');\nconst nock = require('nock');\n\ndescribe('window', function () {\n  before(function (done) {\n    try {\n      nock.activate();\n    } catch(e){\n      //ignore\n    }\n\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    nock.cleanAll();\n    nock.restore();\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.closeWindow()', function (done) {\n    this.client.api.closeWindow(function(res) {\n      assert.strictEqual(res.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.switchWindow()', function (done) {\n    this.client.api.switchWindow('0', function(res) {\n      assert.strictEqual(res.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.switchWindow() - no callback', function (done) {\n    this.client.api.switchWindow('0');\n\n    this.client.start(done);\n  });\n\n  it('client.getWindowSize()', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/window/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: {\n          width: 1000,\n          height: 1000,\n          x: 100,\n          y: 100\n        }\n      })\n    });\n\n    this.client.api.getWindowSize(function(res) {\n      assert.ok(res instanceof Object);\n      assert.deepStrictEqual(res, {\n        width: 1000,\n        height: 1000,\n        x: 100,\n        y: 100\n      });\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.resizeWindow()', function (done) {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/window/rect')\n      .reply(200, function (uri, requestBody) {\n      \n        assert.deepStrictEqual(requestBody, {\n          width: 1000, \n          height: 1000\n        });\n\n        return {\n          sessionId: '1352110219202',\n          status: 0,\n          value: {\n            width: 1000,\n            height: 1000,\n            x: 100,\n            y: 100\n          }\n        };\n      });\n\n    this.client.api.resizeWindow(1000, 1000, function(res) {\n      assert.strictEqual(res.status, 0);\n      assert.strictEqual(res.value, null);\n    });\n  \n    this.client.start(done);\n  });\n  \n  it('client.setWindowSize()', function (done) {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/window/rect')\n      .reply(200, function (uri, requestBody) {\n      \n        assert.deepStrictEqual(requestBody, {\n          width: 1000, \n          height: 1000\n        });\n\n        return {\n          sessionId: '1352110219202',\n          status: 0,\n          value: {\n            width: 1000,\n            height: 1000,\n            x: 100,\n            y: 100\n          }\n        };\n      });\n\n    this.client.api.setWindowSize(1000, 1000, function(res) {\n      assert.strictEqual(res.status, 0);\n      assert.strictEqual(res.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.setWindowPosition()', function (done) {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session/1352110219202/window/rect')\n      .reply(200, function (uri, requestBody) {\n      \n        assert.deepStrictEqual(requestBody, {\n          x: 100, \n          y: 100\n        });\n\n        return {\n          sessionId: '1352110219202',\n          status: 0,\n          value: {\n            width: 1000,\n            height: 1000,\n            x: 100,\n            y: 100\n          }\n        };\n      });\n\n    this.client.api.setWindowPosition(100, 100, function(res) {\n      assert.strictEqual(res.status, 0);\n      assert.strictEqual(res.value, null);\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/commands/window/testWindowCommandsW3C.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\n\ndescribe('window w3c commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('client.setWindowRect()', function (done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/rect',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    });\n\n    this.client.api.setWindowRect({width: 100, height: 100}, function(res) {\n      assert.strictEqual(res.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('client.getWindowRect()', function (done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        value: {\n          width: 1000,\n          height: 1000,\n          x: 100,\n          y: 100\n        }\n      })\n    });\n\n    this.client.api.getWindowRect(function(value) {\n      assert.deepStrictEqual(value, {width: 1000, height: 1000, x: 100, y: 100});\n    });\n\n    this.client.start(done);\n  });\n\n  \n\n});\n\n"
  },
  {
    "path": "test/src/api/commands/window/testWindowNamespaceCommands.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../../lib/globals/commands-w3c.js');\n\ndescribe('.window namespace commands', function () {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .window.close()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window',\n      method: 'DELETE',\n      response: JSON.stringify({\n        status: 0,\n        value: null\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.close(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.open()/openNew()', function(done) {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/window/new',\n        method: 'POST',\n        postdata: {\n          type: 'tab'\n        },\n        response: JSON.stringify({\n          status: 0,\n          value: {handle: 'CDwindow-SOMEHEXCODE123', type: 'tab'}\n        })\n      }, true, true)\n      .addMock({\n        url: '/session/13521-10219-202/window',\n        method: 'POST',\n        postdata: {\n          name: 'CDwindow-SOMEHEXCODE123',\n          handle: 'CDwindow-SOMEHEXCODE123'\n        },\n        response: JSON.stringify({\n          status: 0,\n          value: null\n        })\n      }, true, true);\n\n    const api = this.client.api;\n    this.client.api.window.open(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n    this.client.api.window.openNew(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.open() with type=window', function(done) {\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/window/new',\n        method: 'POST',\n        postdata: {\n          type: 'window'\n        },\n        response: JSON.stringify({\n          status: 0,\n          value: {handle: 'CDwindow-SOMEHEXCODE456', type: 'window'}\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/window',\n        method: 'POST',\n        postdata: {\n          name: 'CDwindow-SOMEHEXCODE456',\n          handle: 'CDwindow-SOMEHEXCODE456'\n        },\n        response: JSON.stringify({\n          status: 0,\n          value: null\n        })\n      }, true);\n\n    const api = this.client.api;\n    this.client.api.window.open('window', function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.getHandle()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window',\n      method: 'GET',\n      response: JSON.stringify({\n        status: 0,\n        value: 'CDwindow-SOMEHEXCODE1223'\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.getHandle(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, 'CDwindow-SOMEHEXCODE1223');\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.getAllHandles()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/handles',\n      method: 'GET',\n      response: JSON.stringify({\n        status: 0,\n        value: ['CDwindow-SOMEHEXCODE1223', 'CDwindow-SOMEHEXCODE456']\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.getAllHandles(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.deepStrictEqual(result.value, ['CDwindow-SOMEHEXCODE1223', 'CDwindow-SOMEHEXCODE456']);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.switchTo()/switch()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window',\n      method: 'POST',\n      postdata: {\n        name: 'CDwindow-SOMEHEXCODE456',\n        handle: 'CDwindow-SOMEHEXCODE456'\n      },\n      response: JSON.stringify({\n        status: 0,\n        value: null\n      })\n    }, true, true);\n\n    const api = this.client.api;\n    this.client.api.window.switchTo('CDwindow-SOMEHEXCODE456', function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n    this.client.api.window.switch('CDwindow-SOMEHEXCODE456', function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.switchTo() -- with error', function(done) {\n    this.client.api.window.switchTo();\n    \n    this.client.start(function(err) {\n      try {\n        assert.ok(err instanceof Error);\n        assert.strictEqual(err.message.includes('windowHandle argument passed to .window.switchTo() must be a string; received: undefined (undefined).'), true);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('test .window.maximize()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/maximize',\n      method: 'POST',\n      postdata: {\n        windowHandle: 'current'\n      },\n      response: JSON.stringify({\n        status: 0,\n        value: {height: 809, width: 1440, x: 0, y: 25}\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.maximize(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.minimize()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/minimize',\n      method: 'POST',\n      postdata: {},\n      response: JSON.stringify({\n        status: 0,\n        value: {height: 763, width: 1200, x: 44, y: 69}\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.minimize(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.fullscreen()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/fullscreen',\n      method: 'POST',\n      postdata: {},\n      response: JSON.stringify({\n        status: 0,\n        value: {height: 900, width: 1440, x: 0, y: 0}\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.fullscreen(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.getPosition()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        status: 0,\n        value: {height: 1011, width: 1200, x: -185, y: -1011}\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.getPosition(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.deepStrictEqual(result.value, {x: -185, y: -1011});\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.getSize()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        status: 0,\n        value: {height: 1011, width: 1200, x: -185, y: -1011}\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.getSize(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.deepStrictEqual(result.value, {height: 1011, width: 1200});\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.getRect()', function(done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/rect',\n      method: 'GET',\n      response: JSON.stringify({\n        status: 0,\n        value: {height: 1011, width: 1200, x: -185, y: -1011}\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.getRect(function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.deepStrictEqual(result.value, {height: 1011, width: 1200, x: -185, y: -1011});\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.setPosition()', function (done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/rect',\n      method: 'POST',\n      postdata: {x: 99, y: 98},\n      response: JSON.stringify({\n        status: 0,\n        value: {width: 1000, height: 1000, x: 99, y: 98}\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.setPosition(99, 98, function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.setPosition() -- with error', function(done) {\n    this.client.api.window.setPosition(87, undefined);\n    \n    this.client.start(function(err) {\n      try {\n        assert.ok(err instanceof Error);\n        assert.strictEqual(err.message.includes('Coordinates passed to .window.getPosition() must be of type number.'), true);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('test .window.setSize()/resize()', function (done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/rect',\n      method: 'POST',\n      postdata: {width: 1076, height: 578},\n      response: JSON.stringify({\n        status: 0,\n        value: {width: 1076, height: 578, x: 100, y: 100}\n      })\n    }, true, true);\n\n    const api = this.client.api;\n    this.client.api.window.setSize(1076, 578, function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n    this.client.api.window.resize(1076, 578, function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.setSize() -- with error', function(done) {\n    this.client.api.window.setSize('876', 678);\n    \n    this.client.start(function(err) {\n      try {\n        assert.ok(err instanceof Error);\n        assert.strictEqual(err.message.includes('First two arguments passed to .window.getPosition() must be of type number.'), true);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('test .window.setRect() -- all properties', function (done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/rect',\n      method: 'POST',\n      postdata: {x: -99, y: 10, width: 1098, height: 574},\n      response: JSON.stringify({\n        status: 0,\n        value: {width: 1098, height: 574, x: -99, y: 10}\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.setRect({width: 1098, height: 574, x: -99, y: 10}, function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.setRect() -- position properties', function (done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/rect',\n      method: 'POST',\n      postdata: {x: 109, y: 76},\n      response: JSON.stringify({\n        status: 0,\n        value: {width: 999, height: 555, x: 109, y: 76}\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.setRect({x: 109, y: 76}, function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.setRect() -- size properties', function (done) {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/window/rect',\n      method: 'POST',\n      postdata: {width: 1001, height: 301},\n      response: JSON.stringify({\n        status: 0,\n        value: {width: 1001, height: 301, x: -99, y: 10}\n      })\n    }, true);\n\n    const api = this.client.api;\n    this.client.api.window.setRect({width: 1001, height: 301}, function callback(result) {\n      assert.strictEqual(this, api);\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value, null);\n    });\n\n    this.client.start(done);\n  });\n\n  it('test .window.setRect() -- only width passed', function(done) {\n    this.client.api.window.setRect({width: 876});\n    \n    this.client.start(function(err) {\n      try {\n        assert.ok(err instanceof Error);\n        assert.strictEqual(err.message.includes('Attributes \"width\" and \"height\" must be specified together when using .window.setRect() command.'), true);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('test .window.setRect() -- only y passed', function(done) {\n    this.client.api.window.setRect({y: 100});\n    \n    this.client.start(function(err) {\n      try {\n        assert.ok(err instanceof Error);\n        assert.strictEqual(err.message.includes('Attributes \"x\" and \"y\" must be specified together when using .window.setRect() command.'), true);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('test .window.setRect() -- with width and y passed', function(done) {\n    this.client.api.window.setRect({width: 1000, y: 5});\n    \n    this.client.start(function(err) {\n      try {\n        assert.ok(err instanceof Error);\n        assert.strictEqual(err.message.includes('Attributes \"width\" and \"height\" must be specified together when using .window.setRect() command.'), true);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('test .window.setRect() -- with error in width', function(done) {\n    this.client.api.window.setRect({width: '677', height: 345, x: 10, y: 10});\n    \n    this.client.start(function(err) {\n      try {\n        assert.ok(err instanceof Error);\n        assert.strictEqual(err.message.includes('Width argument passed to .window.setRect() must be a number; received:'), true);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('test .window.setRect() -- with error in y', function(done) {\n    this.client.api.window.setRect({width: 677, height: 345, x: 10, y: {}});\n    \n    this.client.start(function(err) {\n      try {\n        assert.ok(err instanceof Error);\n        assert.strictEqual(err.message.includes('Y position argument passed to .window.setRect() must be a number; received:'), true);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n});\n\n\n"
  },
  {
    "path": "test/src/api/expect/testExpectActive.js",
    "content": "const assert = require('assert');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst Nocks = require('../../../lib/nocks.js');\n\ndescribe('expect.active', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      output: false,\n      silent: false\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = false;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    Nocks.cleanAll();\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('to be active [PASSED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound().active();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.active;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.waitForMs, 40);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(/^Expected element <#weblogin> to be active \\(\\d+ms\\)$/.test(expect.assertion.message), expect.assertion.message);\n      assert.strictEqual(expect.assertion.messageParts.length, 1, expect.assertion.messageParts);\n    });\n  });\n\n  it('to be active with waitFor [PASSED]', function() {\n    Nocks.elementFound().active();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.active.before(100);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 100);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be active in 100ms'), expect.assertion.message);\n    });\n  });\n\n  it('to be active with waitFor [FAILED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementFound()\n      .notActive()\n      .notActive()\n      .notActive();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.active.before(60);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 60);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be active in 60ms'), expect.assertion.message);\n    });\n  });\n\n  it('to be active [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .notActive()\n      .notActive()\n      .notActive();\n\n    const expect = this.client.api.expect.element('#weblogin').to.be.active;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.waitForMs, 40);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'active');\n      assert.strictEqual(expect.assertion.actual, 'not active');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be active'));\n    });\n  });\n\n  it('to be active with waitFor [PASSED on retry]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    Nocks.elementNotFound().elementFound().active();\n\n    const expect = this.client.api.expect.element('#weblogin').to.be.active.before(60);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 60);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be active in 60ms'));\n    });\n  });\n\n  it('to not be active [PASSED]', function() {\n    Nocks.elementFound().notActive();\n\n    const expect = this.client.api.expect.element('#weblogin').to.not.be.active;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.expected, 'not active');\n      assert.strictEqual(expect.assertion.actual, 'not active');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be active'));\n      assert.strictEqual(expect.assertion.messageParts.length, 1);\n    });\n  });\n\n  it('to not be active [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks\n      .elementFound()\n      .elementFound()\n      .elementFound()\n      .active()\n      .active()\n      .active();\n\n    const expect = this.client.api.expect.element('#weblogin').to.not.be.active;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'not active');\n      assert.strictEqual(expect.assertion.actual, 'active');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be active'));\n    });\n  });\n\n  it('to be active - xpath via useXpath [PASSED]', function() {\n    Nocks.elementFoundXpath().active();\n\n    this.client.api.useXpath();\n    let expect = this.client.api.expect.element('//weblogin').to.be.active;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '//weblogin');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <//weblogin> to be active'));\n    });\n  });\n\n  it('to be active - xpath via argument [PASSED]', function() {\n    Nocks.elementFoundXpath().active();\n\n    let expect = this.client.api.expect.element('//weblogin', 'xpath').to.be.active;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '//weblogin');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <//weblogin> to be active'));\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectAttribute.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\n\ndescribe('expect.attribute', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      output: false,\n      silent: false,\n      globals: {\n        waitForConditionTimeout: 10,\n        waitForConditionPollInterval: 9\n      }\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = true;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('to have attribute [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class');\n    this.client.api.globals.waitForConditionTimeout = 65;\n\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.attribute, 'class');\n      assert.strictEqual(expect.assertion.resultValue, 'hp vasq');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute with waitFor [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').before(100);\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 100);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.abortOnFailure, true);\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have attribute \"class\" in 100ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute with implicit waitFor [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n    this.client.api.globals.abortOnAssertionFailure = false;\n    this.client.api.globals.waitForConditionTimeout = 65;\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 65);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have attribute \"class\" (' + expect.assertion.elapsedTime + 'ms)');\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute with implicit and custom waitFor [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n    this.client.api.globals.abortOnAssertionFailure = false;\n    this.client.api.globals.waitForConditionTimeout = 65;\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').before(100);\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 100);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have attribute \"class\" in 100ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute with waitFor [FAILED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementFound()\n      .attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null);\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').before(60);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 60);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.abortOnFailure, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" in 60ms - attribute was not found'));\n    });\n  });\n\n  it('to have attribute with implicit and custom waitFor [FAILED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    Nocks.elementFound()\n      .attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null);\n\n    this.client.api.globals.waitForConditionTimeout = 65;\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').before(100);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 100);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" in 100ms - attribute was not found'), expect.assertion.message);\n    });\n  });\n\n  it('to have attribute with message [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class', 'Testing if #weblogin has \"class\"');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.includes('Testing if #weblogin has \"class\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute with message [FAILED]', function() {\n    this.client.api.globals.abortOnAssertionFailure = true;\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null);\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class', 'Testing if #weblogin has \"class\"');\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.includes('Testing if #weblogin has \"class\" - attribute was not found'), expect.assertion.message);\n    });\n  });\n\n  it('to have attribute [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null);\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class');\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.waitForMs, 40);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'found');\n      assert.strictEqual(expect.assertion.actual, 'not found');\n      assert.strictEqual(expect.assertion.attribute, 'class');\n      assert.strictEqual(expect.assertion.resultValue, null);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" - attribute was not found'));\n      assert.ok(expect.assertion.messageParts.includes(' - attribute was not found'));\n    });\n  });\n\n  it('to not have attribute [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync(null);\n\n    const expect = this.client.api.expect.element('#weblogin').to.not.have.attribute('class');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.expected, 'not found');\n      assert.strictEqual(expect.assertion.actual, 'not found');\n      assert.strictEqual(expect.assertion.resultValue, null);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not have attribute \"class\"'));\n      assert.ok(/^\\s\\(\\d+ms\\)$/.test(expect.assertion.messageParts[0]));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to not have attribute [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .attributeValueSync('')\n      .attributeValueSync('')\n      .attributeValueSync('')\n      .attributeValueSync('');\n\n    const expect = this.client.api.expect.element('#weblogin').to.not.have.attribute('class');\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'not found');\n      assert.strictEqual(expect.assertion.actual, 'found');\n      assert.strictEqual(expect.assertion.resultValue, '');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not have attribute \"class\"'));\n      assert.ok(/^\\s\\(\\d+ms\\)$/.test(expect.assertion.messageParts[1]), expect.assertion.messageParts);\n    });\n  });\n\n  it('to have attribute - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.waitForMs, 40);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'present');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.resultValue, null);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" - element was not found'));\n      assert.ok(expect.assertion.messageParts.includes(' - element was not found'));\n    });\n  });\n\n  it('to have attribute equal to [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').equal('hp vasq');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" equal to: \"hp vasq\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute which equals [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').which.equals('hp vasq');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" which equals: \"hp vasq\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute which startsWith [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').which.startsWith('hp');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" which starts with: \"hp\"'), 'Failed: ' + expect.assertion.message);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute startWith [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').startWith('hp');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" start with: \"hp\"'), 'Failed: ' + expect.assertion.message);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute which endsWith [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').which.endsWith('vasq');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" which ends with: \"vasq\"'), 'Failed: ' + expect.assertion.message);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute endsWith [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n    const expect = this.client.api.expect.element('#weblogin').attribute('class').endsWith('vasq');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.includes('Expected element <#weblogin> to have attribute \"class\" end with: \"vasq\"'),\n        expect.assertion.message);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute equal to [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .attributeValueSync('hp vasq')\n      .attributeValueSync('hp vasq')\n      .attributeValueSync('hp vasq')\n      .attributeValueSync('hp vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').equal('vasq');\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.expected, 'equal to \\'vasq\\'');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.actual, 'hp vasq');\n      assert.strictEqual(expect.assertion.resultValue, 'hp vasq');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.messageParts.includes(' equal to: \"vasq\"'));\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" equal to: \"vasq\"'));\n    });\n  });\n\n  it('to have attribute NOT equal to [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').not.equal('xx');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.actual, 'hp vasq');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.resultValue, 'hp vasq');\n      assert.strictEqual(expect.assertion.messageParts[0], ' not equal to: \"xx\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" not equal to: \"xx\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute NOT equal to [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .attributeValueSync('hp vasq')\n      .attributeValueSync('hp vasq')\n      .attributeValueSync('hp vasq')\n      .attributeValueSync('hp vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').not.equal('hp vasq');\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.expected, 'not equal to \\'hp vasq\\'');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.actual, 'hp vasq');\n      assert.strictEqual(expect.assertion.resultValue, 'hp vasq');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not equal to: \"hp vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" not equal to: \"hp vasq\"'));\n    });\n  });\n\n  it('to have attribute equal with waitFor [PASSED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 10;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound();\n    Nocks.attributeValueSync(null).attributeValueSync('hp vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').equal('hp vasq').before(110);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 110);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.retries, 1);\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have attribute \"class\" equal to: \"hp vasq\" in 110ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n  });\n\n  it('to have attribute equal with custom waitFor [PASSED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    this.client.api.globals.waitForConditionTimeout = 100;\n    Nocks.elementFound();\n    Nocks.attributeValueSync(null).attributeValueSync('hp vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').equal('hp vasq').before(250);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.retries, 1);\n      assert.strictEqual(expect.assertion.waitForMs, 250);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have attribute \"class\" equal to: \"hp vasq\" in 250ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n  });\n\n  it('to have attribute equal and waitFor [FAILED] - attribute not found', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').equal('hp vasq').before(160);\n    Nocks.attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null);\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.waitForMs, 160);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.retries > 1);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" equal to: \"hp vasq\" in 160ms - attribute was not found'));\n    });\n  });\n\n  it('to have attribute equal and custom waitFor [FAILED] - attribute not found', function() {\n    this.client.api.globals.waitForConditionPollInterval = 100;\n    this.client.api.globals.waitForConditionTimeout = 250;\n    Nocks.elementFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').equal('hp vasq').before(250);\n    Nocks.attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null);\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.waitForMs, 250);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.retries > 1);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" equal to: \"hp vasq\" in 250ms - attribute was not found'));\n    });\n  });\n\n  it('to have attribute equal and waitFor [FAILED] - attribute not equal', function() {\n    this.client.api.globals.waitForConditionPollInterval = 100;\n    Nocks.elementFound().attributeValueSync('xx').attributeValueSync('xx');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').equal('hp vasq').before(101);\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.waitForMs, 101);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.retries >= 1);\n      assert.ok(expect.assertion.elapsedTime >= 101);\n      assert.strictEqual(expect.assertion.expected, 'equal to \\'hp vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" equal to: \"hp vasq\" in 101ms'), expect.assertion.message);\n    });\n  });\n\n  it('to have attribute equal to with message [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('hp vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class', 'Testing if #weblogin has class which equals hp vasq').equal('hp vasq');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Testing if #weblogin has class which equals hp vasq'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute equal with message [FAILED] - attribute not found', function() {\n    Nocks.elementFound()\n      .attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null)\n      .attributeValueSync(null);\n\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class', 'Testing if #weblogin has class which equals hp vasq').equal('hp vasq');\n\n    return this.client.start(function(err) {\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Testing if #weblogin has class which equals hp vasq - attribute was not found'));\n    });\n  });\n\n  it('to have attribute equal with message [FAILED] - attribute not equal', function() {\n    Nocks.elementFound()\n      .attributeValueSync('xx')\n      .attributeValueSync('xx')\n      .attributeValueSync('xx');\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class', 'Testing if #weblogin has class which equals hp vasq').equal('hp vasq');\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.ok(expect.assertion.message.startsWith('Testing if #weblogin has class which equals hp vasq'));\n    });\n  });\n\n  it('to have attribute not contains [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('xx');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').not.contains('vasq');\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'not contain \\'vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not contain: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" not contain: \"vasq\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute not startsWith [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('xx');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').not.startsWith('vasq');\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'not start with \\'vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not start with: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" not start with: \"vasq\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute not endsWith [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('xx');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').not.endsWith('vasq');\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'not end with \\'vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not end with: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" not end with: \"vasq\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute which contains [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').which.contains('vasq');\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'contains \\'vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'vasq');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.resultValue, 'vasq');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[0], ' which ');\n      assert.strictEqual(expect.assertion.messageParts[1], 'contains: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" which contains: \"vasq\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute not contains [FAILED]', function() {\n    Nocks.elementFound()\n      .attributeValueSync('xx')\n      .attributeValueSync('xx')\n      .attributeValueSync('xx')\n      .attributeValueSync('xx');\n\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').not.contains('xx');\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.expected, 'not contain \\'xx\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not contain: \"xx\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" not contain: \"xx\"'));\n    });\n  });\n\n  it('to have attribute not startsWith [FAILED]', function() {\n    Nocks.elementFound()\n      .attributeValueSync('xx')\n      .attributeValueSync('xx')\n      .attributeValueSync('xx')\n      .attributeValueSync('xx');\n\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').not.startsWith('xx');\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.expected, 'not start with \\'xx\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not start with: \"xx\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" not start with: \"xx\"'));\n    });\n  });\n\n  it('to have attribute not endsWith [FAILED]', function() {\n    Nocks.elementFound()\n      .attributeValueSync('xx')\n      .attributeValueSync('xx')\n      .attributeValueSync('xx')\n      .attributeValueSync('xx');\n\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').not.endsWith('xx');\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.expected, 'not end with \\'xx\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not end with: \"xx\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" not end with: \"xx\"'));\n    });\n  });\n\n  it('to have attribute which matches [PASSED]', function(done) {\n    Nocks.elementFound()\n      .attributeValueSync('vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').which.matches(/vasq/);\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'matches \\'/vasq/\\'');\n      assert.strictEqual(expect.assertion.actual, 'vasq');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.resultValue, 'vasq');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[0], ' which ');\n      assert.strictEqual(expect.assertion.messageParts[1], 'matches: \"/vasq/\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" which matches: \"/vasq/\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute not match [PASSED]', function(done) {\n    Nocks.elementFound().attributeValueSync('xx');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').not.match(/vasq/);\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'not match \\'/vasq/\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not match: \"/vasq/\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" not match: \"/vasq/\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute not match [FAILED]', function() {\n    Nocks.elementFound()\n      .attributeValueSync('xx')\n      .attributeValueSync('xx')\n      .attributeValueSync('xx')\n      .attributeValueSync('xx');\n\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').not.match(/xx/);\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.expected, 'not match \\'/xx/\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not match: \"/xx/\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" not match: \"/xx/\"'));\n    });\n  });\n\n  it('to have attribute equal to - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').equal('vasq');\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have attribute \"class\"'));\n\n    return this.client.start(function(err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(expect.assertion.expected, 'equal to \\'vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.resultValue, null);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' equal to: \"vasq\"', ' - element was not found');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" equal to: \"vasq\" - element was not found'));\n    });\n  });\n\n  it('to have attribute contains - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').which.contains('vasq');\n\n    return this.client.start(function(err) {\n      assert.strictEqual(expect.assertion.expected, 'contains \\'vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' which ');\n      assert.strictEqual(expect.assertion.messageParts[1], 'contains: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" which contains: \"vasq\" - element was not found'));\n    });\n  });\n\n  it('to have attribute startsWith - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').which.startsWith('vas');\n\n    return this.client.start(function(err) {\n      assert.strictEqual(expect.assertion.expected, 'starts with \\'vas\\'');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' which ');\n      assert.strictEqual(expect.assertion.messageParts[1], 'starts with: \"vas\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" which starts with: \"vas\" - element was not found'));\n    });\n  });\n\n  it('to have attribute endsWith - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').which.endsWith('sq');\n\n    return this.client.start(function(err) {\n      assert.strictEqual(expect.assertion.expected, 'ends with \\'sq\\'');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' which ');\n      assert.strictEqual(expect.assertion.messageParts[1], 'ends with: \"sq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" which ends with: \"sq\" - element was not found'));\n    });\n  });\n\n  it('to have attribute match - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').which.matches(/vasq$/);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'matches \\'/vasq$/\\'');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.messageParts.includes(' which '));\n      assert.ok(expect.assertion.messageParts.includes('matches: \"/vasq$/\"'));\n      assert.ok(expect.assertion.messageParts.includes(' - element was not found'));\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" which matches: \"/vasq$/\" - element was not found'));\n    });\n  });\n\n  it('to have attribute with waitFor - element not found', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').before(60);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 60);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" in 60ms - element was not found'));\n    });\n  });\n\n  it('to have attribute with custom waitFor - element not found', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    this.client.api.globals.waitForConditionTimeout = 40;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').before(100);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 100);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have attribute \"class\" in 100ms - element was not found'));\n    });\n  });\n\n  it('to have attribute with waitFor - element found on retry', function(done) {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementNotFound().elementFound().attributeValueSync('hp vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').before(60);\n\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 60);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have attribute \"class\" in 60ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute with custom waitFor - element found on retry', function(done) {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    this.client.api.globals.waitForConditionTimeout = 60;\n    Nocks.elementNotFound().elementFound().attributeValueSync('hp vasq');\n\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class').before(100);\n\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 100);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have attribute \"class\" in 100ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have attribute match - throws exception on invalid regex', function() {\n    Nocks.elementFound().attributeValueSync('xx');\n    let expectedError;\n    const expect = this.client.api.expect.element('#weblogin').to.have.attribute('class');\n    try {\n      expect.which.matches('');\n    } catch (err) {\n      expectedError = err;\n    }\n\n    assert.ok(expectedError instanceof Error);\n    assert.strictEqual(expectedError.message, 'matches requires first parameter to be a RegExp. \"string\" given.');\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectCookie.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst {strictEqual, deepStrictEqual} = assert;\n\ndescribe('expect.cookie', function () {\n  describe('with backwards compat mode', function () {\n    beforeEach(function (done) {\n      ExpectGlobals.beforeEach.call(this, {\n        backwards_compatibility_mode: true,\n        output: false,\n        silent: false\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function (done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('to contain [PASSED]', function () {\n      Nocks.cookie('cookie-name', 'cookie-value');\n      let expect = this.client.api.expect.cookie('cookie-name').to.contain('cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to contain: \"cookie-value\"'), expect.assertion.message);\n      });\n    });\n\n    it('contains [PASSED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      let expect = this.client.api.expect.cookie('cookie-name').contains('cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 40);\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to contain: \"cookie-value\"'));\n      });\n    });\n  });\n\n  describe('without compat mode', function () {\n    beforeEach(function (done) {\n      ExpectGlobals.beforeEach.call(this, {\n        output: false,\n        silent: false\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function (done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('to contain [PASSED]', function () {\n      Nocks.cookie('cookie-name', 'cookie-value');\n      let expect = this.client.api.expect.cookie('cookie-name').to.contain('cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to contain: \"cookie-value\"'), expect.assertion.message);\n      });\n    });\n\n    it('contains [PASSED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      let expect = this.client.api.expect.cookie('cookie-name').contains('cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 40);\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to contain: \"cookie-value\"'));\n      });\n    });\n\n    it('toContain [PASSED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      const api = this.client.api.expect.cookie('cookie-name').toContain('cookie-value');\n\n      return this.client.start(function (err) {\n        assert.ok('capabilities' in api);\n        assert.strictEqual(err, undefined);\n      });\n    });\n\n    it('toContain [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n      this.client.api.globals.abortOnAssertionFailure = true;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      const api = this.client.api.expect.cookie('cookie-name').toContain('other-value');\n\n      return this.client.start(function (err) {\n        assert.ok('capabilities' in api);\n        assert.ok(err instanceof Error);\n        assert.ok(/^Expected cookie \"cookie-name\" to contain: \"other-value\" - expected \"contain 'other-value'\" but got: \"cookie-value\" \\(\\d+ms\\)/.test(err.message), err.message);\n      });\n    });\n\n\n    it('toEqual [PASSED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      const api = this.client.api.expect.cookie('cookie-name').toEqual('cookie-value');\n\n      return this.client.start(function (err) {\n        assert.ok('capabilities' in api);\n        assert.strictEqual(err, undefined);\n      });\n    });\n\n    it('toEqual [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n      this.client.api.globals.abortOnAssertionFailure = true;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      const api = this.client.api.expect.cookie('cookie-name').toEqual('other-value');\n\n      return this.client.start(function (err) {\n        assert.ok('capabilities' in api);\n        assert.ok(err instanceof Error);\n        assert.ok(/^Expected cookie \"cookie-name\" to equal: \"other-value\" - expected \"equal 'other-value'\" but got: \"cookie-value\" \\(\\d+ms\\)/.test(err.message), err.message);\n      });\n    });\n\n    it('toMatch [PASSED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      const api = this.client.api.expect.cookie('cookie-name').toMatch(/cookie-value/);\n\n      return this.client.start(function (err) {\n        assert.ok('capabilities' in api);\n        assert.strictEqual(err, undefined);\n      });\n    });\n\n    it('toMatch no regex [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n      let error;\n\n      try {\n        this.client.api.expect.cookie('cookie-name').toMatch('');\n      } catch (err) {\n        error = err;\n      }\n\n      assert.ok(error instanceof Error);\n    });\n\n    it('toMatch [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n      this.client.api.globals.abortOnAssertionFailure = true;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      const api = this.client.api.expect.cookie('cookie-name').toMatch(/other-value/);\n\n      return this.client.start(function (err) {\n        assert.ok('capabilities' in api);\n        assert.ok(err instanceof Error);\n        assert.ok(/^Expected cookie \"cookie-name\" to match: \"\\/other-value\\/\" - expected \"match '\\/other-value\\/'\" but got: \"cookie-value\" \\(\\d+ms\\)/.test(err.message), err.message);\n      });\n    });\n\n    it('not.toEqual [PASSED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      const api = this.client.api.expect.cookie('cookie-name').not.toEqual('other');\n\n      return this.client.start(function (err) {\n        assert.ok('capabilities' in api);\n        assert.strictEqual(err, undefined);\n      });\n    });\n\n    it('not.toEqual [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n      this.client.api.globals.abortOnAssertionFailure = true;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      const api = this.client.api.expect.cookie('cookie-name').not.toEqual('cookie-value');\n\n      return this.client.start(function (err) {\n        assert.ok('capabilities' in api);\n        assert.ok(err instanceof Error);\n        assert.ok(/^Expected cookie \"cookie-name\" to not equal: \"cookie-value\" - expected \"not equal 'cookie-value'\" but got: \"cookie-value\" \\(\\d+ms\\)/.test(err.message), err.message);\n      });\n    });\n\n    it('to equal to [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.equal('other-cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'equal \\'other-cookie-value\\'');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.actual, 'cookie-value');\n        strictEqual(expect.assertion.resultValue, 'cookie-value');\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.messageParts[0], ' equal: \"other-cookie-value\"');\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to equal: \"other-cookie-value\"'));\n      });\n    });\n\n    it('to NOT equal to [PASSED]', function () {\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.not.equal('xx');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.resultValue, 'cookie-value');\n        strictEqual(expect.assertion.messageParts[0], ' not equal: \"xx\"');\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to not equal: \"xx\"'));\n      });\n    });\n\n    it('to NOT equal to [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.not.equal('cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'cookie-value');\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.messageParts[0], ' not equal: \"cookie-value\"');\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to not equal: \"cookie-value\"'),\n          `Message was: ${expect.assertion.message}`);\n      });\n    });\n\n    it('to equal waitFor [PASSED]', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n      Nocks.cookie('cookie-name', 'other');\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.equal('cookie-value').before(110);\n      Nocks.cookie('cookie-name', 'cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 110);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.retries, 1);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to equal: \"cookie-value\" in 110ms (' + expect.assertion.elapsedTime + 'ms)'));\n      });\n    });\n\n    it('to equal and waitFor [FAILED] - value not equal', function () {\n      this.client.api.globals.waitForConditionTimeout = 10;\n      this.client.api.globals.waitForConditionPollInterval = 250;\n\n      Nocks.cookie('cookie-name', 'other');\n      Nocks.cookie('cookie-name', 'other');\n      Nocks.cookie('cookie-name', 'other');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.equal('cookie-value').before(250);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 250);\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.retries >= 1);\n        strictEqual(expect.assertion.message, `Expected cookie \"cookie-name\" to equal: \"cookie-value\" in 250ms - expected \"equal 'cookie-value'\" but got: \"other\" (${expect.assertion.elapsedTime}ms)`);\n      });\n    });\n\n\n    it('to not contains [PASSED]', function () {\n      Nocks.cookie('cookie-name', 'other');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.not.contains('vasq');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'not contain \\'vasq\\'');\n        strictEqual(expect.assertion.actual, 'other');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'other');\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.messageParts[0], ' not contain: \"vasq\"');\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to not contain: \"vasq\"'));\n      });\n    });\n\n\n    it('with domain to contain [PASSED]', function () {\n      Nocks.cookie('cookie-name', 'cookie-value');\n      let expect = this.client.api.expect.cookie('cookie-name', 'cookie-domain').to.contain('cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" for domain \"cookie-domain\" to contain: \"cookie-value\"'),\n          `Message: ${expect.assertion.message}`);\n      });\n    });\n\n    it('with domain to equal - cookie not found [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks\n        .cookieNotFound()\n        .cookieNotFound()\n        .cookieNotFound();\n      let expect = this.client.api.expect.cookie('cookie-name', 'cookie-domain').to.equal('other-cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" for domain \"cookie-domain\" to equal: \"other-cookie-value\" - no cookie \"cookie-name\" for domain \"cookie-domain\" was found - expected \"equal \\'other-cookie-value\\'\" but got: \"[NotFoundError]\"'), expect.assertion.message);\n      });\n    });\n\n    it('with domain to contain [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n      let expect = this.client.api.expect.cookie('cookie-name', 'cookie-domain').to.contain('other-cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" for domain \"cookie-domain\" to contain: \"other-cookie-value\"'));\n      });\n    });\n\n    it('with domain to NOT contain [PASSED]', function () {\n      Nocks.cookie('cookie-name', 'cookie-value');\n      let expect = this.client.api.expect.cookie('cookie-name', 'cookie-domain').not.to.contain('other-cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" for domain \"cookie-domain\" to not contain: \"other-cookie-value\"'), expect.assertion.message);\n      });\n    });\n\n    it('with domain to NOT contain [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.cookie('cookie-name', 'cookie-value');\n      Nocks.cookie('cookie-name', 'cookie-value');\n      let expect = this.client.api.expect.cookie('cookie-name', 'cookie-domain').not.to.contain('cookie-value');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" for domain \"cookie-domain\" to not contain: \"cookie-value\"'), expect.assertion.message);\n      });\n    });\n\n\n    it('to not contain [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.cookie('cookie-name', 'other');\n      Nocks.cookie('cookie-name', 'other');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.not.contains('other');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'other');\n        strictEqual(expect.assertion.passed, false);\n        assert.deepStrictEqual(expect.assertion.messageParts[0], ' not contain: \"other\"');\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to not contain: \"other\"'));\n      });\n    });\n\n    it('to not match [PASSED]', function () {\n      Nocks.cookie('cookie-name', 'other');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.not.match(/vasq/);\n\n      return this.client.start(function () {\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to'));\n        strictEqual(expect.assertion.expected, 'not match \\'/vasq/\\'');\n        strictEqual(expect.assertion.actual, 'other');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'other');\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.messageParts[0], ' not match: \"/vasq/\"');\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to not match: \"/vasq/\"'));\n      });\n    });\n\n    it('to not match [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.cookie('cookie-name', 'other');\n      Nocks.cookie('cookie-name', 'other');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.not.match(/other/);\n\n      return this.client.start(function () {\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to'));\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'other');\n        strictEqual(expect.assertion.passed, false);\n        assert.deepStrictEqual(expect.assertion.messageParts[0], ' not match: \"/other/\"');\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to not match: \"/other/\"'));\n      });\n    });\n\n    it('to equal to - cookie not found', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.cookie('', 'other');\n      Nocks.cookie('', 'other');\n      let expect = this.client.api.expect.cookie('cookie-name').to.equal('vasq');\n\n      return this.client.start(function () {\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to equal: \"vasq\" - no cookie \"cookie-name\" was found'), expect.assertion.message);\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.resultValue, undefined);\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.messageParts.includes(' equal: \"vasq\"'));\n        assert.ok(expect.assertion.messageParts.includes(' - no cookie \"cookie-name\" was found'));\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to equal: \"vasq\" - no cookie \"cookie-name\" was found'));\n      });\n    });\n\n    it('to equal with waitFor - cookie found on retry', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n      Nocks.cookie('', 'other');\n      Nocks.cookie('cookie-name', 'hp vasq');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.equal('hp vasq').before(60);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 60);\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to equal: \"hp vasq\" in 60ms (' + expect.assertion.elapsedTime + 'ms)'));\n      });\n    });\n\n    it('to match - throws exception on invalid regex', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.cookie('cookie-name', 'other');\n      Nocks.cookie('cookie-name', 'other');\n\n      let expect = this.client.api.expect.cookie('cookie-name');\n      assert.throws(function () {\n        expect.matches('');\n      }.bind(this));\n\n      return this.client.start();\n    });\n\n    it('to equal and waitFor [FAILED] - value not found', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n      Nocks.cookie('cookie-name', 'other');\n      Nocks.cookie('cookie-name', 'other');\n      Nocks.cookie('cookie-name', 'other');\n\n      let expect = this.client.api.expect.cookie('cookie-name').to.equal('hp vasq').before(60);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 60);\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.retries >= 1);\n        assert.ok(expect.assertion.message.startsWith('Expected cookie \"cookie-name\" to equal: \"hp vasq\" in 60ms'));\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectCount.js",
    "content": "const assert = require('assert');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst Nocks = require('../../../lib/nocks.js');\n\ndescribe('expect.elements count', function() {\n\n  describe('with backwards compat mode', function() {\n    beforeEach(function(done) {\n      ExpectGlobals.beforeEach.call(this, {\n        backwards_compatibility_mode: true,\n        output: false,\n        silent: false\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function(done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('count to equal [PASSED]', function() {\n      Nocks.elementsFound('.classname');\n      let expect = this.client.api.expect.elements('.classname').count.to.equal(4);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected elements <.classname> count to equal: \"4\"'), expect.assertion.message);\n      });\n    });\n\n    it('count to equal [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementsFound('.classname');\n      Nocks.elementsFound('.classname');\n\n      let expect = this.client.api.expect.elements('.classname').count.to.equal(5);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.expected, 'equal \\'5\\'');\n        assert.strictEqual(expect.assertion.negate, false);\n        assert.strictEqual(expect.assertion.actual, 4);\n        assert.strictEqual(expect.assertion.resultValue, 4);\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.messageParts.includes(' equal: \"5\"'));\n        assert.ok(expect.assertion.message.startsWith('Expected elements <.classname> count to equal: \"5\"'), expect.assertion.message);\n      });\n    });\n  });\n\n  describe('without compat mode', function() {\n    beforeEach(function(done) {\n      ExpectGlobals.beforeEach.call(this, {\n        silent: false,\n        output: false\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function(done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('count to equal [PASSED]', function() {\n      Nocks.elementsFound('.classname');\n      let expect = this.client.api.expect.elements('.classname').count.to.equal(4);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected elements <.classname> count to equal: \"4\"'), expect.assertion.message);\n      });\n    });\n\n    it('count to equal [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementsFound('.classname');\n      Nocks.elementsFound('.classname');\n\n      let expect = this.client.api.expect.elements('.classname').count.to.equal(5);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.expected, 'equal \\'5\\'');\n        assert.strictEqual(expect.assertion.negate, false);\n        assert.strictEqual(expect.assertion.actual, 4);\n        assert.strictEqual(expect.assertion.resultValue, 4);\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.messageParts.includes(' equal: \"5\"'));\n        assert.ok(expect.assertion.message.startsWith('Expected elements <.classname> count to equal: \"5\"'), expect.assertion.message);\n      });\n    });\n\n    it('count to NOT equal [PASSED]', function() {\n      Nocks.elementsFound('.classname');\n\n      let expect = this.client.api.expect.elements('.classname').count.to.not.equal(888);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.negate, true);\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.strictEqual(expect.assertion.resultValue, 4);\n        assert.strictEqual(expect.assertion.messageParts[0], ' not equal: \"888\"');\n        assert.ok(expect.assertion.message.startsWith('Expected elements <.classname> count to not equal: \"888\"'));\n      });\n    });\n\n    it('count to NOT equal [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementsFound('.classname');\n      Nocks.elementsFound('.classname');\n\n      let expect = this.client.api.expect.elements('.classname').count.to.not.equal(4);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.expected, 'not equal \\'4\\'');\n        assert.strictEqual(expect.assertion.negate, true);\n        assert.strictEqual(expect.assertion.actual, 4);\n        assert.strictEqual(expect.assertion.resultValue, 4);\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.startsWith('Expected elements <.classname> count to not equal: \"4\"'));\n      });\n    });\n\n    it('count to equal with waitFor [PASSED]', function() {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n      Nocks.elementsNotFound('.classname');\n      Nocks.elementsFound('.classname');\n\n      let expect = this.client.api.expect.elements('.classname').count.to.equal(4).before(100);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.waitForMs, 100);\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.strictEqual(expect.assertion.retries, 1);\n        assert.ok(expect.assertion.message.startsWith('Expected elements <.classname> count to equal: \"4\" in 100ms (' + expect.assertion.elapsedTime + 'ms)'));\n      });\n    });\n\n    it('count to equal and waitFor [FAILED] - count not equal', function() {\n      this.client.api.globals.waitForConditionPollInterval = 100;\n\n      Nocks.elementsFound('.classname');\n      Nocks.elementsFound('.classname');\n      Nocks.elementsFound('.classname');\n\n      let expect = this.client.api.expect.elements('.classname').count.to.equal(888).before(105);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.waitForMs, 105);\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.retries >= 1);\n        assert.ok(expect.assertion.elapsedTime >= 105);\n        assert.strictEqual(expect.assertion.expected, 'equal \\'888\\'');\n        assert.ok(expect.assertion.message.startsWith('Expected elements <.classname> count to equal: \"888\" in 105ms'), expect.assertion.message);\n      });\n    });\n\n    it('count to equal - element not found', function() {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementsNotFound('.classname');\n      Nocks.elementsNotFound('.classname');\n\n      let expect = this.client.api.expect.elements('.classname').count.to.equal(4);\n\n      return this.client.start(function() {\n        assert.ok(expect.assertion.message.startsWith('Expected elements <.classname> count to'));\n        assert.strictEqual(expect.assertion.expected, 'equal \\'4\\'');\n        assert.strictEqual(expect.assertion.negate, false);\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.messageParts.includes(' equal: \"4\"'));\n        assert.ok(expect.assertion.message.startsWith('Expected elements <.classname> count to equal: \"4\"'));\n        assert.strictEqual(expect.assertion.resultValue, 0);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectCss.js",
    "content": "const assert = require('assert');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst Nocks = require('../../../lib/nocks.js');\n\ndescribe('expect.css', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, () => {\n      this.client.api.globals.abortOnAssertionFailure = false;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('to have css property [PASSED]', function() {\n    Nocks.elementFound().cssProperty('block');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.cssProperty, 'display');\n      assert.strictEqual(expect.assertion.resultValue, 'block');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\"'));\n      assert.strictEqual(expect.assertion.messageParts.length, 1);\n    });\n  });\n\n  it('to have css property with waitFor [PASSED]', function() {\n    Nocks.elementFound().cssProperty('block');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').before(100);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 100);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" in 100ms (' + expect.assertion.elapsedTime + 'ms)'));\n    });\n  });\n\n  it('to have css property with waitFor [FAILED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 15;\n    this.client.api.globals.waitForConditionTimeout = 50;\n\n    Nocks.elementFound().cssProperty('', 4);\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').before(40);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.passed, false, 'Assertion should fail');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" in 40ms'));\n    });\n  });\n\n  it('to have css property with message [PASSED]', function() {\n    Nocks.elementFound().cssProperty('block');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display', 'Testing if #weblogin has display');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.includes('Testing if #weblogin has display'));\n    });\n  });\n\n  it('to have css property with message [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .cssProperty('')\n      .cssProperty('')\n      .cssProperty('');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display', 'Testing if #weblogin has display');\n\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.includes('Testing if #weblogin has display'));\n    });\n\n    return this.client.start();\n  });\n\n  it('to have css property [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .cssProperty('')\n      .cssProperty('')\n      .cssProperty('');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.waitForMs, 40);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'present');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.cssProperty, 'display');\n      assert.strictEqual(expect.assertion.resultValue, '');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\"'));\n      assert.strictEqual(expect.assertion.messageParts.length, 2);\n    });\n  });\n\n  it('to not have css property [PASSED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .cssProperty('')\n      .cssProperty('')\n      .cssProperty('');\n\n    let expect = this.client.api.expect.element('#weblogin').to.not.have.css('display');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.expected, 'not present');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.resultValue, '');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not have css property \"display\"'));\n      assert.strictEqual(expect.assertion.messageParts.length, 1);\n    });\n  });\n\n  it('to not have css property [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .cssProperty('x')\n      .cssProperty('x')\n      .cssProperty('x');\n\n    let expect = this.client.api.expect.element('#weblogin').to.not.have.css('display');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'not present');\n      assert.strictEqual(expect.assertion.actual, 'present');\n      assert.strictEqual(expect.assertion.resultValue, 'x');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not have css property \"display\"'));\n      assert.strictEqual(expect.assertion.messageParts.length, 2);\n    });\n  });\n\n  it('to have css property - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 65;\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .cssProperty(null);\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.waitForMs, 65);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'present');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.resultValue, null);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" - element was not found'));\n      assert.ok(expect.assertion.messageParts.includes(' - element was not found'));\n    });\n  });\n\n  it('to have css property equal to [PASSED]', function() {\n    Nocks.elementFound().cssProperty('block');\n    this.client.api.globals.waitForConditionTimeout = 65;\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').equal('block');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 65);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" equal to: \"block\"'));\n    });\n  });\n\n  it('to have css property which equals [PASSED]', function() {\n    Nocks.elementFound().cssProperty('block');\n    this.client.api.globals.waitForConditionTimeout = 100;\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').which.equals('block');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 100);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" which equals: \"block\"'));\n    });\n  });\n\n  it('to have css property equal to [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .cssProperty('block')\n      .cssProperty('block')\n      .cssProperty('block');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').equal('b');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'equal to \\'b\\'');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.actual, 'block');\n      assert.strictEqual(expect.assertion.resultValue, 'block');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' equal to: \"b\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" equal to: \"b\"'));\n    });\n  });\n\n  it('to have css property NOT equal to [PASSED]', function() {\n    Nocks.elementFound().cssProperty('block');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').not.equal('xx');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.resultValue, 'block');\n      assert.strictEqual(expect.assertion.messageParts[0], ' not equal to: \"xx\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" not equal to: \"xx\"'));\n    });\n  });\n\n  it('to have css property NOT equal to [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .cssProperty('block')\n      .cssProperty('block')\n      .cssProperty('block');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').not.equal('block');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'not equal to \\'block\\'');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.actual, 'block');\n      assert.strictEqual(expect.assertion.resultValue, 'block');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not equal to: \"block\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" not equal to: \"block\"'));\n    });\n  });\n\n  it('to have css property equal with waitFor [PASSED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    Nocks.elementFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').equal('block').before(110);\n    Nocks.cssProperty('').cssProperty('block');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 110);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.retries, 1);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" equal to: \"block\" in 110ms (' + expect.assertion.elapsedTime + 'ms)'), expect.assertion.message);\n    });\n  });\n\n  it('to have css property equal and waitFor [FAILED] - property not set', function() {\n    this.client.api.globals.waitForConditionPollInterval = 100;\n    Nocks.elementFound().cssProperty('', 3);\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').equal('block').before(250);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 250);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.retries > 1);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" equal to: \"block\" in 250ms'));\n    });\n  });\n\n  it('to have css property equal and waitFor [FAILED] - property not equal', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    Nocks.elementFound().cssProperty('xx', 3);\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').equal('block').before(100);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 100);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.retries >= 1);\n      assert.ok(expect.assertion.elapsedTime >= 100);\n      assert.strictEqual(expect.assertion.expected, 'equal to \\'block\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" equal to: \"block\" in 100ms'));\n    });\n  });\n\n  it('to have css property which contains [PASSED]', function() {\n    Nocks.elementFound().cssProperty('block');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').which.contains('block');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'contains \\'block\\'');\n      assert.strictEqual(expect.assertion.actual, 'block');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.resultValue, 'block');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[1], 'contains: \"block\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" which contains: \"block\"'));\n    });\n  });\n  it('to have css property equal with message [PASSED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 200;\n    Nocks.elementFound().cssProperty('block');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display', 'Testing if #weblogin has display which equals block').equal('block');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.actual, 'block');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.includes('Testing if #weblogin has display which equals block'));\n    });\n  });\n\n  it('to have css property equal with message [FAILED] - property not set', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .cssProperty('')\n      .cssProperty('')\n      .cssProperty('');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display', 'Testing if #weblogin has display which equals block').equal('block');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.includes('Testing if #weblogin has display which equals block'));\n    });\n  });\n\n  it('to have css property equal with message [FAILED] - property not equal', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    Nocks.elementFound()\n      .cssProperty('xx')\n      .cssProperty('xx')\n      .cssProperty('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display', 'Testing if #weblogin has display which equals block').equal('block');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.ok(expect.assertion.message.includes('Testing if #weblogin has display which equals block'));\n    });\n  });\n\n  it('to have css property not contains [PASSED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    Nocks.elementFound()\n      .cssProperty('xx')\n      .cssProperty('xx')\n      .cssProperty('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').not.contains('vasq');\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s to have css property \"display\"'));\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'not contain \\'vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not contain: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" not contain: \"vasq\"'));\n    });\n  });\n\n  it('to have css property not contains [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    Nocks.elementFound()\n      .cssProperty('xx')\n      .cssProperty('xx')\n      .cssProperty('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').not.contains('xx');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'not contain \\'xx\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not contain: \"xx\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" not contain: \"xx\"'));\n    });\n  });\n\n  it('to have css property which matches [PASSED]', function() {\n    Nocks.elementFound().cssProperty('block');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').which.matches(/block/);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'matches \\'/block/\\'');\n      assert.strictEqual(expect.assertion.actual, 'block');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.resultValue, 'block');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[0], ' which ');\n      assert.strictEqual(expect.assertion.messageParts[1], 'matches: \"/block/\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" which matches: \"/block/\"'));\n    });\n  });\n\n  it('to have css property not match [PASSED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    Nocks.elementFound()\n      .cssProperty('xx')\n      .cssProperty('xx')\n      .cssProperty('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').not.match(/vasq/);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'not match \\'/vasq/\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not match: \"/vasq/\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" not match: \"/vasq/\"'));\n    });\n  });\n\n  it('to have css property not match [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    Nocks.elementFound()\n      .cssProperty('xx')\n      .cssProperty('xx')\n      .cssProperty('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').not.match(/xx/);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'not match \\'/xx/\\'');\n      assert.strictEqual(expect.assertion.actual, 'xx');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.resultValue, 'xx');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' not match: \"/xx/\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" not match: \"/xx/\"'));\n    });\n  });\n\n  it('to have css property equal to - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').equal('vasq');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'equal to \\'vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.resultValue, null);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' equal to: \"vasq\"');\n      assert.strictEqual(expect.assertion.messageParts[1], ' - element was not found');\n    });\n  });\n\n  it('to have css property contains - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').which.contains('vasq');\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'contains \\'vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' which ');\n      assert.strictEqual(expect.assertion.messageParts[1], 'contains: \"vasq\"');\n      assert.strictEqual(expect.assertion.messageParts[2], ' - element was not found');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" which contains: \"vasq\" - element was not found'));\n    });\n  });\n\n  it('to have css property with waitFor - element not found', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').before(60);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 60);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" in 60ms - element was not found'));\n    });\n  });\n\n  it('to have css property with waitFor - element found on retry', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementNotFound().elementFound().cssProperty('block');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').before(60);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 60);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" in 60ms (' + expect.assertion.elapsedTime + 'ms)'));\n    });\n  });\n\n  it('to have css property match - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').which.matches(/vasq$/);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.expected, 'matches \\'/vasq$/\\'');\n      assert.strictEqual(expect.assertion.actual, 'not present');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.messageParts[0], ' which ');\n      assert.strictEqual(expect.assertion.messageParts[1], 'matches: \"/vasq$/\"');\n      assert.strictEqual(expect.assertion.messageParts[2], ' - element was not found');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have css property \"display\" which matches: \"/vasq$/\" - element was not found'));\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectEnabled.js",
    "content": "const assert = require('assert');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst Nocks = require('../../../lib/nocks.js');\n\ndescribe('expect.enabled', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, () => {\n      this.client.api.globals.abortOnAssertionFailure = false;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    Nocks.cleanAll();\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('to be enabled [PASSED]', function() {\n    Nocks.elementFound().enabled();\n    let expect = this.client.api.expect.element('#weblogin').to.be.enabled;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.resultValue, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be enabled'));\n      assert.strictEqual(expect.assertion.messageParts.length, 1);\n    });\n  });\n\n  it('to be enabled with waitFor [PASSED]', function() {\n    Nocks.elementFound().enabled();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.enabled.before(100);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 100);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be enabled in 100ms (' + expect.assertion.elapsedTime + 'ms)'));\n    });\n  });\n\n  it('to be enabled with waitFor [FAILED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementFound().notEnabled(3);\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.enabled.before(60);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 60);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be enabled in 60ms'), expect.assertion.message);\n    });\n  });\n\n  it('to be enabled [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .notEnabled()\n      .notEnabled()\n      .notEnabled();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.enabled;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.waitForMs, 40);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'enabled');\n      assert.strictEqual(expect.assertion.actual, 'not enabled');\n      assert.strictEqual(expect.assertion.resultValue, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be enabled'));\n      assert.strictEqual(expect.assertion.messageParts.length, 2);\n    });\n  });\n\n  it('to not be enabled [PASSED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .notEnabled()\n      .notEnabled()\n      .notEnabled();\n\n    let expect = this.client.api.expect.element('#weblogin').to.not.be.enabled;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.expected, 'not enabled');\n      assert.strictEqual(expect.assertion.actual, 'not enabled');\n      assert.strictEqual(expect.assertion.resultValue, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be enabled'));\n      assert.strictEqual(expect.assertion.messageParts.length, 1);\n    });\n  });\n\n  it('to not be enabled [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .enabled()\n      .enabled()\n      .enabled();\n\n    let expect = this.client.api.expect.element('#weblogin').to.not.be.enabled;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'not enabled');\n      assert.strictEqual(expect.assertion.actual, 'enabled');\n      assert.strictEqual(expect.assertion.resultValue, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be enabled'));\n      assert.strictEqual(expect.assertion.messageParts.length, 2);\n    });\n  });\n\n  it('to be enabled - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.enabled;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.waitForMs, 40);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'enabled');\n      assert.strictEqual(expect.assertion.actual, 'not found');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be enabled - element was not found'));\n      assert.ok(expect.assertion.messageParts.includes(' - element was not found'));\n    });\n  });\n\n  it('to not be enabled with waitFor [FAILED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementFound().enabled(4);\n\n    let expect = this.client.api.expect.element('#weblogin').to.not.be.enabled.before(120);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 120);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be enabled in 120ms'));\n    });\n  });\n\n  it('to be enabled with waitFor - element not found', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.enabled.before(60);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 60);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'enabled');\n      assert.strictEqual(expect.assertion.actual, 'not found');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be enabled in 60ms - element was not found'));\n    });\n  });\n\n  it('to be enabled with waitFor - element found on retry', function() {\n    this.client.api.globals.waitForConditionPollInterval = 100;\n\n    Nocks.elementNotFound().elementFound().enabled();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.enabled.before(111);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.waitForMs, 111);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be enabled in 111ms (' + expect.assertion.elapsedTime + 'ms)'));\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectPresent.js",
    "content": "const assert = require('assert');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst Nocks = require('../../../lib/nocks.js');\n\ndescribe('expect.present', function() {\n\n  describe('with backwards compat mode', function() {\n    beforeEach(function(done) {\n      ExpectGlobals.beforeEach.call(this, {\n        output: false,\n        silent: false,\n        backwards_compatibility_mode: true\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function(done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('to be present with waitFor [PASSED]', function() {\n      Nocks.elementFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.be.present.before(100);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.waitForMs, 100);\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be present in 100ms (' + expect.assertion.elapsedTime + 'ms)'));\n      });\n    });\n\n    it('to be present with waitFor [FAILED]', function() {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementNotFound()\n        .elementNotFound()\n        .elementNotFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.be.present.before(60);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.waitForMs, 60);\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be present in 60ms - element was not found'));\n      });\n    });\n  });\n\n  describe('without compat mode', function() {\n    beforeEach(function(done) {\n      ExpectGlobals.beforeEach.call(this, {\n        output: false,\n        silent: false\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function(done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('to be present [PASSED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .elementFound()\n        .elementFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.be.present;\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.selector, '#weblogin');\n        assert.strictEqual(expect.assertion.negate, false);\n        assert.strictEqual(expect.assertion.waitForMs, 40);\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.ok(/^Expected element <#weblogin> to be present \\(\\d+ms\\)$/.test(expect.assertion.message), expect.assertion.message);\n        assert.strictEqual(expect.assertion.messageParts.length, 1);\n      });\n    });\n\n    it('to be present with waitFor [PASSED]', function() {\n      Nocks.elementFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.be.present.before(100);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.waitForMs, 100);\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be present in 100ms (' + expect.assertion.elapsedTime + 'ms)'));\n      });\n    });\n\n    it('to be present with waitFor [FAILED]', function() {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementNotFound()\n        .elementNotFound()\n        .elementNotFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.be.present.before(60);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.waitForMs, 60);\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be present in 60ms - element was not found'));\n      });\n    });\n\n    it('to be present [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementNotFound()\n        .elementNotFound()\n        .elementNotFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.be.present;\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.selector, '#weblogin');\n        assert.strictEqual(expect.assertion.negate, false);\n        assert.strictEqual(expect.assertion.waitForMs, 40);\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.strictEqual(expect.assertion.expected, 'present');\n        assert.strictEqual(expect.assertion.actual, 'not present');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be present - element was not found'));\n        assert.strictEqual(expect.assertion.messageParts[0], ' - element was not found');\n      });\n    });\n\n    it('to be present with waitFor [PASSED on retry]', function() {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n      Nocks.elementNotFound().elementFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.be.present.before(60);\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.waitForMs, 60);\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be present in 60ms (' + expect.assertion.elapsedTime + 'ms)'));\n      });\n    });\n\n    it('to not be present [PASSED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementNotFound()\n        .elementNotFound()\n        .elementNotFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.not.be.present;\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.selector, '#weblogin');\n        assert.strictEqual(expect.assertion.negate, true);\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.strictEqual(expect.assertion.expected, 'not present');\n        assert.strictEqual(expect.assertion.actual, 'not present');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be present'));\n        assert.strictEqual(expect.assertion.messageParts.length, 2);\n      });\n    });\n\n    it('to not be present [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .elementFound()\n        .elementFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.not.be.present;\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.selector, '#weblogin');\n        assert.strictEqual(expect.assertion.negate, true);\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.strictEqual(expect.assertion.expected, 'not present');\n        assert.strictEqual(expect.assertion.actual, 'present');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be present'));\n        assert.strictEqual(expect.assertion.messageParts.length, 2);\n      });\n    });\n\n    it('to be present - xpath via useXpath [PASSED]', function() {\n      Nocks.elementFoundXpath();\n\n      this.client.api.useXpath();\n      let expect = this.client.api.expect.element('//weblogin').to.be.present;\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.selector, '//weblogin');\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected element <//weblogin> to be present'));\n      });\n    });\n\n    it('to be present - xpath via argument [PASSED]', function() {\n      Nocks.elementFoundXpath();\n\n      let expect = this.client.api.expect.element('//weblogin', 'xpath').to.be.present;\n\n      return this.client.start(function() {\n        assert.strictEqual(expect.assertion.selector, '//weblogin');\n        assert.strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected element <//weblogin> to be present'));\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectProperty.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\n\ndescribe('expect.property', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      silent: false,\n      output: false\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = true;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('to have property which matches [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue('vasq');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.property('className').which.matches(/vasq/);\n\n    assert.strictEqual(expect.assertion.message, 'Expected element %s to have dom property \"className\"');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'matches \\'/vasq/\\'');\n      assert.strictEqual(expect.assertion.actual, 'vasq');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.resultValue, 'vasq');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.messageParts[0], ' which ');\n      assert.strictEqual(expect.assertion.messageParts[1], 'matches: \"/vasq/\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have dom property \"className\" which matches: \"/vasq/\"'));\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have property equals [PASSED] - selector object', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue('vasq');\n\n    const expect = this.client.api.expect.element({\n      selector: '#weblogin'\n    }).to.have.property('className').equals('vasq');\n\n    assert.strictEqual(expect.assertion.message, 'Expected element %s to have dom property \"className\"');\n\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'equal to \\'vasq\\'');\n      assert.strictEqual(expect.assertion.actual, 'vasq');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.resultValue, 'vasq');\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have dom property \"className\" equal to: \"vasq\"'), expect.assertion.message);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have property equals [FAILED] - selector object', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue('vasq')\n      .propertyValue('vasq')\n      .propertyValue('vasq');\n\n    const expect = this.client.api.expect.element({\n      selector: '#weblogin',\n      timeout: 150,\n      retryInterval: 100,\n      abortOnFailure: false\n    }).to.have.property('className').equals('qq');\n\n    this.client.api.perform(function() {\n      assert.ok(expect.assertion.retries >= 1);\n      assert.strictEqual(expect.assertion.expected, 'equal to \\'qq\\'');\n      assert.strictEqual(expect.assertion.actual, 'vasq');\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.strictEqual(expect.assertion.resultValue, 'vasq');\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have dom property \"className\" equal to: \"qq\"'), expect.assertion.message);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have property equals [FAILED] - selector object and custom message', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue('vasq')\n      .propertyValue('vasq')\n      .propertyValue('vasq');\n\n    const expect = this.client.api.expect.element({\n      selector: '#weblogin',\n      timeout: 30,\n      retryInterval: 20,\n      abortOnFailure: false,\n      message: 'custom assert message %s'\n    }).to.have.property('className').equals('qq');\n\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(/^custom assert message <#weblogin> - expected \"equal to 'qq'\" but got: \"vasq\" \\(\\d.+\\)$/.test(expect.assertion.message), expect.assertion.message);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have property which deep equals [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue(['class-one', 'class-two'], 'classList');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.property('classList').equal(['class-one', 'class-two']);\n\n    assert.strictEqual(expect.assertion.message, 'Expected element %s to have dom property \"classList\"');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'equal to \\'class-one,class-two\\'');\n      assert.deepStrictEqual(expect.assertion.actual, ['class-one', 'class-two']);\n      assert.strictEqual(expect.assertion.negate, false);\n      assert.deepStrictEqual(expect.assertion.resultValue, ['class-one', 'class-two']);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have dom property \"classList\" equal to: \"class-one,class-two\"'), expect.assertion.message);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have property which contains [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue(['class-one', 'class-two'], 'classList');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.property('classList').contain('class-one');\n\n    assert.strictEqual(expect.assertion.message, 'Expected element %s to have dom property \"classList\"');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'contain \\'class-one\\'');\n      assert.deepStrictEqual(expect.assertion.actual, ['class-one', 'class-two']);\n      assert.strictEqual(expect.assertion.negate, false);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have property which contains and custom waitFor [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue(['class-one', 'class-two'], 'classList');\n\n    this.client.api.globals.abortOnAssertionFailure = false;\n    this.client.api.globals.waitForConditionTimeout = 65;\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.property('classList').contain('class-one').before(100);\n\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have dom property \"classList\" contain: \"class-one\" in 100ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have property which contains and custom waitFor [FAILED] - element not found', function(done) {\n    Nocks\n      .elementNotFound()\n      .elementNotFound();\n\n    this.client.api.globals.abortOnAssertionFailure = false;\n    this.client.api.globals.waitForConditionTimeout = 65;\n    this.client.api.globals.waitForConditionPollInterval = 55;\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.property('classList').contain('class-one').before(50);\n\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have dom property \"classList\" contain: \"class-one\" in 50ms - element was not found - expected \"contain \\'class-one\\'\" but got: \"not present\" (' + expect.assertion.elapsedTime + 'ms)');\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have property contains [FAILED] - property not found', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue(null, 'classList')\n      .propertyValue(null, 'classList')\n      .propertyValue(null, 'classList');\n\n    this.client.api.globals.abortOnAssertionFailure = false;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    this.client.api.globals.waitForConditionTimeout = 25;\n\n    const expect = this.client.api.expect.element('#weblogin')\n      .to.have.property('classList').contain('class-one');\n\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have dom property \"classList\" contain: \"class-one\" - property was not found - expected \"contain \\'class-one\\'\" but got: \"null\" (' + expect.assertion.elapsedTime + 'ms)');\n    });\n\n    this.client.start(done);\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectSelected.js",
    "content": "const assert = require('assert');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst Nocks = require('../../../lib/nocks.js');\nconst {strictEqual} = assert;\n\ndescribe('expect.selected', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      globals: {\n        abortOnAssertionFailure: false\n      }\n    }, () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    Nocks.cleanAll();\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  const {runExpectAssertion} = ExpectGlobals;\n\n  it('to be selected [PASSED]', function() {\n    Nocks.elementFound().selected();\n\n    return runExpectAssertion.call(this, {\n      element: '#weblogin',\n      fn(expect) {\n        expect.to.be.selected;\n      },\n      assertion({selector, negate, passed, resultValue, message, messageParts, elapsedTime}) {\n        strictEqual(selector, '#weblogin');\n        strictEqual(negate, false);\n        strictEqual(passed, true);\n        strictEqual(resultValue, true);\n        strictEqual(message, `Expected element <#weblogin> to be selected (${elapsedTime}ms)`);\n        strictEqual(messageParts.length, 1, messageParts);\n      }\n    });\n  });\n\n  it('to be selected with waitFor [PASSED]', function() {\n    Nocks.elementFound().selected();\n\n    return runExpectAssertion.call(this, {\n      element: '#weblogin',\n      fn(expect) {\n        expect.to.be.selected.before(100);\n      },\n      assertion({waitForMs, passed, message, elapsedTime}) {\n        strictEqual(waitForMs, 100);\n        strictEqual(passed, true);\n        strictEqual(message, `Expected element <#weblogin> to be selected in 100ms (${elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('to be selected with waitFor [FAILED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementFound().notSelected(3);\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.selected.before(60);\n\n    return this.client.start(function() {\n      const {elapsedTime, waitForMs, passed, message} = expect.assertion;\n\n      assert.strictEqual(waitForMs, 60);\n      assert.strictEqual(passed, false);\n      assert.strictEqual(message, `Expected element <#weblogin> to be selected in 60ms - expected \"selected\" but got: \"not selected\" (${elapsedTime}ms)`);\n    });\n  });\n\n  it('to be selected [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .notSelected()\n      .notSelected()\n      .notSelected();\n\n    return runExpectAssertion.call(this, {\n      element: '#weblogin',\n      fn(expect) {\n        expect.to.be.selected;\n      },\n      assertion({waitForMs, selector, actual, negate, resultValue, expected, passed, message, elapsedTime}) {\n        strictEqual(selector, '#weblogin');\n        strictEqual(negate, false);\n        strictEqual(waitForMs, 40);\n        strictEqual(passed, false);\n        strictEqual(expected, 'selected');\n        strictEqual(actual, 'not selected');\n        strictEqual(resultValue, false);\n        strictEqual(message, `Expected element <#weblogin> to be selected - expected \"selected\" but got: \"not selected\" (${elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('to not be selected [PASSED]', function() {\n    Nocks.elementFound().notSelected();\n\n    let expect = this.client.api.expect.element('#weblogin').to.not.be.selected;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.expected, 'not selected');\n      assert.strictEqual(expect.assertion.actual, 'not selected');\n      assert.strictEqual(expect.assertion.resultValue, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be selected'));\n      assert.strictEqual(expect.assertion.messageParts.length, 1);\n    });\n  });\n\n  it('to not be selected [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .selected()\n      .selected()\n      .selected();\n\n    let expect = this.client.api.expect.element('#weblogin').to.not.be.selected;\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.selector, '#weblogin');\n      assert.strictEqual(expect.assertion.negate, true);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.strictEqual(expect.assertion.expected, 'not selected');\n      assert.strictEqual(expect.assertion.actual, 'selected');\n      assert.strictEqual(expect.assertion.resultValue, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be selected'));\n      assert.strictEqual(expect.assertion.messageParts.length, 2);\n    });\n  });\n\n  it('to be selected - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    const expect = this.client.api.expect.element('#weblogin').to.be.selected;\n\n    return this.client.start(function() {\n      const {elapsedTime, selector, negate, waitForMs, passed, expected, actual, message} = expect.assertion;\n\n      assert.strictEqual(selector, '#weblogin');\n      assert.strictEqual(negate, false);\n      assert.strictEqual(waitForMs, 40);\n      assert.strictEqual(passed, false);\n      assert.strictEqual(expected, 'selected');\n      assert.strictEqual(actual, 'not found');\n      assert.strictEqual(message, `Expected element <#weblogin> to be selected - element was not found - expected \"selected\" but got: \"not found\" (${elapsedTime}ms)`);\n      assert.ok(expect.assertion.messageParts.includes(' - element was not found'));\n    });\n  });\n\n  it('to not be selected with waitFor [FAILED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementFound().selected(3);\n\n    let expect = this.client.api.expect.element('#weblogin').to.not.be.selected.before(120);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 120);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be selected in 120ms'));\n    });\n  });\n\n  it('to be selected with waitFor - element not found', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.selected.before(60);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 60);\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be selected in 60ms - element was not found'));\n    });\n  });\n\n  it('to be selected with waitFor - element found on retry', function() {\n    this.client.api.globals.waitForConditionPollInterval = 100;\n\n    Nocks\n      .elementNotFound()\n      .elementFound()\n      .selected();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.selected.before(111);\n\n    return this.client.start(function() {\n      assert.strictEqual(expect.assertion.waitForMs, 111);\n      assert.strictEqual(expect.assertion.passed, true);\n      assert.strictEqual(expect.assertion.message, 'Expected element <#weblogin> to be selected in 111ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectText.js",
    "content": "const assert = require('assert');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst Nocks = require('../../../lib/nocks.js');\nconst {strictEqual} = assert;\n\ndescribe('expect.text', function() {\n  const {runExpectAssertion} = ExpectGlobals;\n\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, () => {\n      this.client.api.globals.abortOnAssertionFailure = false;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    Nocks.cleanAll();\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('text to equal [PASSED]', function() {\n    Nocks.elementFound().text('hp vasq');\n    let expect = this.client.api.expect.element('#weblogin').text.to.equal('hp vasq');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to equal: \"hp vasq\"'));\n    });\n  });\n\n  it('text to equal [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .text('hp vasq')\n      .text('hp vasq')\n      .text('hp vasq');\n\n    return runExpectAssertion.call(this, {\n      fn: expect => expect.text.to.equal('vasq'),\n\n      assertion({expected, negate, actual, resultValue, passed, messageParts, message, elapsedTime}) {\n        strictEqual(expected, 'equal \\'vasq\\'');\n        strictEqual(negate, false);\n        strictEqual(actual, 'hp vasq');\n        strictEqual(resultValue, 'hp vasq');\n        strictEqual(passed, false);\n        strictEqual(messageParts.length, 3);\n        strictEqual(message, `Expected element <#weblogin> text to equal: \"vasq\" - expected \"equal 'vasq'\" but got: \"hp vasq\" (${elapsedTime}ms)`);\n      }\n    });\n\n  });\n\n  it('text to NOT equal [PASSED]', function() {\n    Nocks.elementFound().text('hp vasq');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.not.equal('xx');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.resultValue, 'hp vasq');\n      strictEqual(expect.assertion.messageParts[0], ' not equal: \"xx\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to not equal: \"xx\"'));\n    });\n  });\n\n  it('text to NOT equal [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .text('hp vasq')\n      .text('hp vasq')\n      .text('hp vasq');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.not.equal('hp vasq');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'not equal \\'hp vasq\\'');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.actual, 'hp vasq');\n      strictEqual(expect.assertion.resultValue, 'hp vasq');\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.message, `Expected element <#weblogin> text to not equal: \"hp vasq\" - expected \"not equal 'hp vasq'\" but got: \"hp vasq\" (${expect.assertion.elapsedTime}ms)`);\n    });\n  });\n\n  it('text to equal with waitFor [PASSED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    Nocks.elementFound();\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.equal('hp vasq').before(100);\n    Nocks.text(null).text('hp vasq');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.waitForMs, 100);\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.retries, 1);\n      strictEqual(expect.assertion.message, 'Expected element <#weblogin> text to equal: \"hp vasq\" in 100ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n  });\n\n  it('text to equal and waitFor [FAILED] - text not equal', function() {\n    this.client.api.globals.waitForConditionPollInterval = 150;\n\n    Nocks.elementFound().text('xx', 3);\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.equal('hp vasq').before(100);\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.waitForMs, 100);\n      strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.retries >= 1);\n      assert.ok(expect.assertion.elapsedTime >= 100);\n      strictEqual(expect.assertion.expected, 'equal \\'hp vasq\\'');\n      //strictEqual(expect.assertion.actual, 'xx');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to equal: \"hp vasq\" in 100ms'));\n    });\n  });\n\n  it('text to not equal [PASSED]', function() {\n    Nocks.elementFound().text('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.not.equal('vasq');\n    assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'not equal \\'vasq\\'');\n      strictEqual(expect.assertion.actual, 'xx');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.resultValue, 'xx');\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.messageParts[0], ' not equal: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to not equal: \"vasq\"'));\n    });\n  });\n\n  it('text to not equal [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .text('xx')\n      .text('xx')\n      .text('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.not.equal('xx');\n    assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'not equal \\'xx\\'');\n      strictEqual(expect.assertion.actual, 'xx');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.resultValue, 'xx');\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.messageParts[0], ' not equal: \"xx\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to not equal: \"xx\"'));\n    });\n  });\n\n  it('text to not contain [PASSED]', function() {\n    Nocks.elementFound().text('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.not.contain('vasq');\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'not contain \\'vasq\\'');\n      strictEqual(expect.assertion.actual, 'xx');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.resultValue, 'xx');\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.messageParts[0], ' not contain: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to not contain: \"vasq\"'));\n    });\n  });\n\n  it('text to contain [PASSED]', function() {\n    Nocks.elementFound().text('vasq');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.contain('vasq');\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'contain \\'vasq\\'');\n      strictEqual(expect.assertion.actual, 'vasq');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.resultValue, 'vasq');\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.messageParts[0], ' contain: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to contain: \"vasq\"'));\n    });\n  });\n\n  it('text to startWith [PASSED]', function() {\n    Nocks.elementFound().text('vasq');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.startWith('va');\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'start with \\'va\\'');\n      strictEqual(expect.assertion.actual, 'vasq');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.resultValue, 'vasq');\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.messageParts[0], ' start with: \"va\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to start with: \"va\"'));\n    });\n  });\n\n  it('text to endWith [PASSED]', function() {\n    Nocks.elementFound().text('vasq');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.endWith('sq');\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'end with \\'sq\\'');\n      strictEqual(expect.assertion.actual, 'vasq');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.resultValue, 'vasq');\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.messageParts[0], ' end with: \"sq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to end with: \"sq\"'));\n    });\n  });\n\n  it('text to not contain [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .text('xx')\n      .text('xx')\n      .text('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.not.contains('xx');\n    assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'not contain \\'xx\\'');\n      strictEqual(expect.assertion.actual, 'xx');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.resultValue, 'xx');\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.message, `Expected element <#weblogin> text to not contain: \"xx\" - expected \"not contain 'xx'\" but got: \"xx\" (${expect.assertion.elapsedTime}ms)`);\n    });\n  });\n\n  it('text to match [PASSED]', function() {\n    Nocks.elementFound().text('vasq');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.match(/vasq/);\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'match \\'/vasq/\\'');\n      strictEqual(expect.assertion.actual, 'vasq');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.resultValue, 'vasq');\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.messageParts[0], ' match: \"/vasq/\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to match: \"/vasq/\"'));\n    });\n  });\n\n  it('text to not match [PASSED]', function() {\n    Nocks.elementFound().text('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.not.match(/vasq/);\n\n    assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'not match \\'/vasq/\\'');\n      strictEqual(expect.assertion.actual, 'xx');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.resultValue, 'xx');\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.messageParts[0], ' not match: \"/vasq/\"');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to not match: \"/vasq/\"'));\n    });\n  });\n\n  it('text to not match [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .text('xx')\n      .text('xx')\n      .text('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.not.match(/xx/);\n    assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'not match \\'/xx/\\'');\n      strictEqual(expect.assertion.actual, 'xx');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.resultValue, 'xx');\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.message, `Expected element <#weblogin> text to not match: \"/xx/\" - expected \"not match '/xx/'\" but got: \"xx\" (${expect.assertion.elapsedTime}ms)`);\n    });\n  });\n\n  it('text to equal - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    return runExpectAssertion.call(this, {\n      fn: expect => {\n        expect.text.to.equal('vasq');\n        assert.ok(expect.assertion.message.startsWith('Expected element %s text to'));\n      },\n\n      assertion({expected, negate, actual, resultValue, passed, messageParts, message, elapsedTime}) {\n        strictEqual(expected, 'equal \\'vasq\\'');\n        strictEqual(actual, 'not present');\n        strictEqual(negate, false);\n        strictEqual(resultValue, null);\n        strictEqual(passed, false);\n        assert.ok(messageParts.includes(' equal: \"vasq\"'));\n        assert.ok(messageParts.includes(' - element was not found'));\n        strictEqual(message, `Expected element <#weblogin> text to equal: \"vasq\" - element was not found - expected \"equal 'vasq'\" but got: \"not present\" (${elapsedTime}ms)`);\n      }\n    });\n  });\n\n  it('text to contain - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.contain('vasq');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'contain \\'vasq\\'');\n      strictEqual(expect.assertion.actual, 'not present');\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.message, `Expected element <#weblogin> text to contain: \"vasq\" - element was not found - expected \"contain 'vasq'\" but got: \"not present\" (${expect.assertion.elapsedTime}ms)`);\n    });\n  });\n\n  it('text to match - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.match(/vasq$/);\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'match \\'/vasq$/\\'');\n      strictEqual(expect.assertion.actual, 'not present');\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.message, `Expected element <#weblogin> text to match: \"/vasq$/\" - element was not found - expected \"match '/vasq$/'\" but got: \"not present\" (${expect.assertion.elapsedTime}ms)`);\n    });\n  });\n\n  it('text to match with waitFor - element not found', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.match(/vasq$/).before(60);\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.waitForMs, 60);\n      strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> text to match: \"/vasq$/\" in 60ms - element was not found'));\n    });\n  });\n\n  it('text to match with waitFor - element found on retry', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementNotFound().elementFound().text('hp vasq');\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.match(/vasq$/).before(60);\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.waitForMs, 60);\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.message, 'Expected element <#weblogin> text to match: \"/vasq$/\" in 60ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n  });\n\n  it('text to match - throws exception on invalid regex', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .text('xx')\n      .text('xx')\n      .text('xx');\n\n    let expect = this.client.api.expect.element('#weblogin').text;\n    assert.throws(function() {\n      expect.which.matches('');\n    }.bind(this));\n\n    return this.client.start();\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectTitle.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst {strictEqual} = assert;\n\ndescribe('expect.title', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      output: false,\n      silent: false\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = false;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    Nocks.cleanAll();\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('to contain [PASSED]', function() {\n    Nocks.title('hp vasq');\n    let expect = this.client.api.expect.title().to.contain('hp vasq');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected page title to contain: \"hp vasq\"'));\n    });\n  });\n\n  it('toEqual [PASSED]', function() {\n    Nocks.title('hp vasq');\n    let api = this.client.api.expect.title().to.toEqual('hp vasq');\n\n    return this.client.start(function(err) {\n      assert.ok('capabilities' in api);\n      assert.strictEqual(err, undefined);\n    });\n  });\n\n  it('toEqual [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 10;\n    this.client.api.globals.waitForConditionPollInterval = 9;\n    this.client.api.globals.abortOnAssertionFailure = true;\n\n    Nocks.title('hp vasq').title('hp vasq').title('hp vasq').title('hp vasq');\n    \n    let api = this.client.api.expect.title().to.toEqual('vasq');\n\n    return this.client.start(function(err) {\n      assert.ok('capabilities' in api);\n      assert.ok(err instanceof Error);\n      assert.ok(/^Expected page title to equal: \"vasq\" - expected \"equal 'vasq'\" but got: \"hp vasq\" \\(\\d+ms\\)$/.test(err.message), err.message);\n    });\n  });\n\n  it('contains [PASSED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.title('hp vasq');\n\n    let expect = this.client.api.expect.title().contains('hp vasq');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.waitForMs, 40);\n      strictEqual(expect.assertion.passed, true);\n      assert.ok(expect.assertion.message.startsWith('Expected page title to contain: \"hp vasq\"'));\n    });\n  });\n\n  it('to equal to [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.title('hp vasq').title('hp vasq');\n\n    let expect = this.client.api.expect.title().to.equal('vasq');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'equal \\'vasq\\'');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.actual, 'hp vasq');\n      strictEqual(expect.assertion.resultValue, 'hp vasq');\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.messageParts[0], ' equal: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected page title to equal: \"vasq\"'));\n    });\n  });\n\n  it('to  NOT equal to [PASSED]', function() {\n    Nocks.title('hp vasq');\n\n    let expect = this.client.api.expect.title().to.not.equal('xx');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.resultValue, 'hp vasq');\n      strictEqual(expect.assertion.messageParts[0], ' not equal: \"xx\"');\n      assert.ok(expect.assertion.message.startsWith('Expected page title to not equal: \"xx\"'));\n    });\n  });\n\n  it('to  NOT equal to [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks\n      .title('hp vasq')\n      .title('hp vasq');\n\n    let expect = this.client.api.expect.title().to.not.equal('hp vasq');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'not equal \\'hp vasq\\'');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.actual, 'hp vasq');\n      strictEqual(expect.assertion.resultValue, 'hp vasq');\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.messageParts[0], ' not equal: \"hp vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected page title to not equal: \"hp vasq\"'));\n    });\n  });\n\n  it('to equal waitFor [PASSED]', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n    Nocks.title('');\n\n    let expect = this.client.api.expect.title().to.equal('hp vasq').before(40);\n    Nocks.title('hp vasq');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.waitForMs, 40);\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.retries, 1);\n      strictEqual(expect.assertion.message, 'Expected page title to equal: \"hp vasq\" in 40ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n  });\n\n  it('to equal and waitFor [FAILED] - value not equal', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks\n      .title('xx')\n      .title('xx');\n\n    let expect = this.client.api.expect.title().to.equal('hp vasq').before(40);\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.waitForMs, 40);\n      strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.retries >= 1);\n      assert.ok(expect.assertion.elapsedTime >= 40);\n      strictEqual(expect.assertion.expected, 'equal \\'hp vasq\\'');\n      strictEqual(expect.assertion.actual, 'xx');\n      assert.ok(expect.assertion.message.startsWith('Expected page title to equal: \"hp vasq\" in 40ms'));\n    });\n  });\n\n  it('to not equal to [PASSED]', function() {\n    Nocks.title('xx');\n\n    let expect = this.client.api.expect.title().to.not.equal('vasq');\n    assert.ok(expect.assertion.message.startsWith('Expected page title to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'not equal \\'vasq\\'');\n      strictEqual(expect.assertion.actual, 'xx');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.resultValue, 'xx');\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.messageParts[0], ' not equal: \"vasq\"');\n      assert.ok(expect.assertion.message.startsWith('Expected page title to not equal: \"vasq\"'));\n    });\n  });\n\n  it('to not equal to [FAILED]', function() {\n\n    // No need to retry\n    this.client.api.globals.waitForConditionTimeout = 0;\n    \n    Nocks.title('xx');\n\n    let expect = this.client.api.expect.title().to.not.equal('xx');\n    assert.ok(expect.assertion.message.startsWith('Expected page title to'));\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.expected, 'not equal \\'xx\\'');\n      strictEqual(expect.assertion.actual, 'xx');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.resultValue, 'xx');\n      strictEqual(expect.assertion.passed, false);\n      assert.deepStrictEqual(expect.assertion.messageParts[0], ' not equal: \"xx\"');\n      assert.ok(expect.assertion.message.startsWith('Expected page title to not equal: \"xx\"'));\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectType.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst {strictEqual} = assert;\n\ndescribe('expect.type', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, () => {\n      this.client.api.globals.abortOnAssertionFailure = false;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    Nocks.cleanAll();\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('to be [PASSED]', function() {\n    Nocks.elementFound().name('input');\n\n    const expect = this.client.api.expect.element('#weblogin').to.be.an('input');\n\n    return this.client.start(function(err) {\n      if (err) {\n        return Promise.reject(err);\n      }\n      strictEqual(expect.assertion.selector, '#weblogin');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.article, 'an');\n      strictEqual(expect.assertion.resultValue, 'input');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be an input'));\n      strictEqual(expect.assertion.messageParts.length, 1);\n    });\n  });\n\n  it('to be [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks\n      .elementFound()\n      .name('div')\n      .name('div')\n      .name('div');\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.an('input');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.selector, '#weblogin');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.waitForMs, 40);\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.expected, 'be an input');\n      strictEqual(expect.assertion.actual, 'div');\n      strictEqual(expect.assertion.article, 'an');\n      strictEqual(expect.assertion.resultValue, 'div');\n      strictEqual(expect.assertion.message, `Expected element <#weblogin> to be an input - expected \"be an input\" but got: \"div\" (${expect.assertion.elapsedTime}ms)`);\n      strictEqual(expect.assertion.messageParts.length, 2);\n    });\n  });\n\n  it('to not be [PASSED]', function() {\n    Nocks.elementFound().name('input');\n\n    let expect = this.client.api.expect.element('#weblogin').to.not.be.a('div');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.selector, '#weblogin');\n      strictEqual(expect.assertion.article, 'a');\n      strictEqual(expect.assertion.negate, true);\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.expected, 'not be a div');\n      strictEqual(expect.assertion.actual, 'input');\n      strictEqual(expect.assertion.resultValue, 'input');\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be a div'));\n      strictEqual(expect.assertion.messageParts.length, 1);\n    });\n  });\n\n  it('to not be [PASSED] with upper case', function() {\n    Nocks.elementFound().name('INPUT');\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    let expect = this.client.api.expect.element('#weblogin').to.be.an('input');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.passed, true);\n    });\n  });\n\n  it('to not be [FAILED] with upper case', function() {\n    Nocks.elementFound().name('INPUT');\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    let expect = this.client.api.expect.element('#weblogin').to.not.be.an('input');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.passed, false);\n    });\n  });\n\n  it('to not be [PASSED] with regex', function() {\n    Nocks.elementFound().name('INPUT');\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    let expect = this.client.api.expect.element('#weblogin').to.be.an(/^input/i);\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.passed, true);\n    });\n  });\n\n  it('to not be [FAILED] with regex', function() {\n    Nocks.elementFound().name('INPUT');\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    let expect = this.client.api.expect.element('#weblogin').to.not.be.an(/^input/i);\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.passed, false);\n    });\n  });\n\n  it('to not be - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.an('input');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.selector, '#weblogin');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.waitForMs, 40);\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.expected, 'present');\n      strictEqual(expect.assertion.actual, 'not present');\n      strictEqual(expect.assertion.resultValue, null);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be an input - element was not found'));\n      assert.ok(expect.assertion.messageParts.includes(' - element was not found'));\n    });\n  });\n\n  it('to be with message [PASSED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .name('input')\n      .name('input')\n      .name('input');\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.an('input', 'weblogin should be an input');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.selector, '#weblogin');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.waitForMs, 40);\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.article, 'an');\n      strictEqual(expect.assertion.resultValue, 'input');\n      strictEqual(expect.assertion.message, `weblogin should be an input (${expect.assertion.elapsedTime}ms)`);\n    });\n  });\n\n  it('to be with message [FAILED]', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks.elementFound()\n      .name('div')\n      .name('div')\n      .name('div');\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.an('input', 'weblogin should be an input');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.selector, '#weblogin');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.waitForMs, 40);\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.expected, 'be an input');\n      strictEqual(expect.assertion.actual, 'div');\n      strictEqual(expect.assertion.article, 'an');\n      strictEqual(expect.assertion.resultValue, 'div');\n      strictEqual(expect.assertion.message, `weblogin should be an input - expected \"be an input\" but got: \"div\" (${expect.assertion.elapsedTime}ms)`);\n      strictEqual(expect.assertion.messageParts.length, 0);\n    });\n  });\n\n  it('to be with message - element not found', function() {\n    this.client.api.globals.waitForConditionTimeout = 40;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n\n    Nocks\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.an('input', 'weblogin should be an input');\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.selector, '#weblogin');\n      strictEqual(expect.assertion.negate, false);\n      strictEqual(expect.assertion.waitForMs, 40);\n      strictEqual(expect.assertion.passed, false);\n      strictEqual(expect.assertion.expected, 'present');\n      strictEqual(expect.assertion.actual, 'not present');\n      strictEqual(expect.assertion.resultValue, null);\n      strictEqual(expect.assertion.message, `weblogin should be an input - element was not found - expected \"present\" but got: \"not present\" (${expect.assertion.elapsedTime}ms)`);\n    });\n  });\n\n  it('to be with waitFor - element not found', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.an('input').before(60);\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.waitForMs, 60);\n      strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be an input in 60ms - element was not found'));\n    });\n  });\n\n  it('to be with waitFor - element found on retry', function() {\n    this.client.api.globals.waitForConditionPollInterval = 50;\n\n    Nocks.elementNotFound().elementFound().name('input');\n\n    let expect = this.client.api.expect.element('#weblogin').to.be.an('input').before(60);\n\n    return this.client.start(function() {\n      strictEqual(expect.assertion.waitForMs, 60);\n      strictEqual(expect.assertion.passed, true);\n      strictEqual(expect.assertion.message, 'Expected element <#weblogin> to be an input in 60ms (' + expect.assertion.elapsedTime + 'ms)');\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectUrl.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst {strictEqual} = assert;\n\ndescribe('expect.url', function() {\n  describe('with backwards compat mode', function() {\n    beforeEach(function(done) {\n      ExpectGlobals.beforeEach.call(this, {\n        backwards_compatibility_mode: true,\n        output: false,\n        silent: false\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function(done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('to contain [PASSED]', function() {\n      Nocks.url().getUrl();\n      let expect = this.client.api.expect.url().to.contain('localhost');\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected current url to contain: \"localhost\"'), expect.assertion.message);\n      });\n    });\n\n    it('contains [PASSED] with retries', function() {\n      this.client.api.globals.waitForConditionTimeout = 100;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks\n        .url()\n        .getUrl('about:blank')\n        .getUrl();\n\n      let expect = this.client.api.expect.url().contains('localhost');\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.retries, 1);\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected current url to contain: \"localhost\"'));\n      });\n    });\n\n    it('to equal to [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 10;\n      this.client.api.globals.waitForConditionPollInterval = 9;\n\n      Nocks.url().getUrl().getUrl().getUrl();\n\n      let expect = this.client.api.expect.url().to.equal('vasq');\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.actual, 'http://localhost');\n        strictEqual(expect.assertion.resultValue, 'http://localhost');\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.messageParts[0], ' equal: \"vasq\"');\n        assert.ok(expect.assertion.message.startsWith('Expected current url to equal: \"vasq\"'));\n      });\n    });\n  });\n\n  describe('without compat mode', function() {\n    beforeEach(function(done) {\n      ExpectGlobals.beforeEach.call(this, {\n        output: false,\n        silent: false\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function(done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('to contain [PASSED]', function() {\n      Nocks.url().getUrl();\n      let expect = this.client.api.expect.url().to.contain('localhost');\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected current url to contain: \"localhost\"'), expect.assertion.message);\n      });\n    });\n\n    it('contains [PASSED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 10;\n      this.client.api.globals.waitForConditionPollInterval = 9;\n\n      Nocks.url().getUrl().getUrl().getUrl();\n\n      let expect = this.client.api.expect.url().contains('localhost');\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.waitForMs, 10);\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected current url to contain: \"localhost\"'));\n      });\n    });\n\n    it('contains [PASSED] with retries', function() {\n      this.client.api.globals.waitForConditionTimeout = 100;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks\n        .url()\n        .getUrl('about:blank')\n        .getUrl();\n\n      let expect = this.client.api.expect.url().contains('localhost');\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.retries, 1);\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected current url to contain: \"localhost\"'));\n      });\n    });\n\n    it('to equal to [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 10;\n      this.client.api.globals.waitForConditionPollInterval = 9;\n\n      Nocks.url().getUrl().getUrl().getUrl();\n\n      let expect = this.client.api.expect.url().to.equal('vasq');\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.actual, 'http://localhost');\n        strictEqual(expect.assertion.resultValue, 'http://localhost');\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.messageParts[0], ' equal: \"vasq\"');\n        assert.ok(expect.assertion.message.startsWith('Expected current url to equal: \"vasq\"'));\n      });\n    });\n\n    it('to equal waitFor [PASSED]', function() {\n      this.client.api.globals.waitForConditionPollInterval = 10;\n      Nocks.url().getUrl();\n\n      let expect = this.client.api.expect.url().contains('localhost').before(5);\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.waitForMs, 5);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.retries, 0);\n        strictEqual(expect.assertion.message, 'Expected current url to contain: \"localhost\" in 5ms (' + expect.assertion.elapsedTime + 'ms)');\n      });\n    });\n\n    it('to NOT equal to [PASSED]', function() {\n      Nocks.url().getUrl();\n\n      let expect = this.client.api.expect.url().to.not.equal('xx');\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.resultValue, 'http://localhost');\n        strictEqual(expect.assertion.messageParts[0], ' not equal: \"xx\"');\n        assert.ok(expect.assertion.message.startsWith('Expected current url to not equal: \"xx\"'));\n      });\n    });\n\n    it('to NOT equal to [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 10;\n      this.client.api.globals.waitForConditionPollInterval = 9;\n\n      Nocks.url().getUrl().getUrl().getUrl();\n\n      let expect = this.client.api.expect.url().to.not.equal('http://localhost');\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.actual, 'http://localhost');\n        strictEqual(expect.assertion.resultValue, 'http://localhost');\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.messageParts[0], ' not equal: \"http://localhost\"');\n        assert.ok(expect.assertion.message.startsWith('Expected current url to not equal: \"http://localhost\"'));\n      });\n    });\n\n    it('to not equal to [PASSED]', function() {\n      Nocks.url().getUrl();\n\n      let expect = this.client.api.expect.url().to.not.equal('vasq');\n      assert.ok(expect.assertion.message.startsWith('Expected current url to'));\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.expected, 'not equal \\'vasq\\'');\n        strictEqual(expect.assertion.actual, 'http://localhost');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'http://localhost');\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.messageParts[0], ' not equal: \"vasq\"');\n        assert.ok(expect.assertion.message.startsWith('Expected current url to not equal: \"vasq\"'));\n      });\n    });\n\n    it('to not equal to [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 0;\n\n      Nocks.url().getUrl();\n\n      let expect = this.client.api.expect.url().to.not.equal('http://localhost');\n      assert.ok(expect.assertion.message.startsWith('Expected current url to'));\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.expected, 'not equal \\'http://localhost\\'');\n        strictEqual(expect.assertion.actual, 'http://localhost');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'http://localhost');\n        strictEqual(expect.assertion.passed, false);\n        assert.deepStrictEqual(expect.assertion.messageParts[0], ' not equal: \"http://localhost\"');\n        assert.ok(expect.assertion.message.startsWith('Expected current url to not equal: \"http://localhost\"'));\n      });\n    });\n\n    it('to not contains [PASSED]', function() {\n      Nocks.url().getUrl();\n\n      let expect = this.client.api.expect.url().to.not.contains('vasq');\n\n      assert.ok(expect.assertion.message.startsWith('Expected current url to'));\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.expected, 'not contain \\'vasq\\'');\n        strictEqual(expect.assertion.actual, 'http://localhost');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'http://localhost');\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.messageParts[0], ' not contain: \"vasq\"');\n        assert.ok(expect.assertion.message.startsWith('Expected current url to not contain: \"vasq\"'));\n      });\n    });\n\n\n\n    it('to not contain [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 10;\n      this.client.api.globals.waitForConditionPollInterval = 9;\n\n      Nocks.url().getUrl().getUrl().getUrl().getUrl();\n\n      let expect = this.client.api.expect.url().to.not.contains('http://localhost');\n      assert.ok(expect.assertion.message.startsWith('Expected current url to'));\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.expected, 'not contain \\'http://localhost\\'');\n        strictEqual(expect.assertion.actual, 'http://localhost');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'http://localhost');\n        strictEqual(expect.assertion.passed, false);\n        assert.deepStrictEqual(expect.assertion.messageParts[0], ' not contain: \"http://localhost\"');\n        assert.ok(expect.assertion.message.startsWith('Expected current url to not contain: \"http://localhost\"'));\n      });\n    });\n\n    it('to not match [PASSED]', function() {\n      Nocks.url().getUrl();\n\n      let expect = this.client.api.expect.url().to.not.match(/vasq/);\n\n      assert.ok(expect.assertion.message.startsWith('Expected current url to'));\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.expected, 'not match \\'/vasq/\\'');\n        strictEqual(expect.assertion.actual, 'http://localhost');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'http://localhost');\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.messageParts[0], ' not match: \"/vasq/\"');\n        assert.ok(expect.assertion.message.startsWith('Expected current url to not match: \"/vasq/\"'));\n      });\n    });\n\n    it('to not match [FAILED]', function() {\n      this.client.api.globals.waitForConditionTimeout = 10;\n      this.client.api.globals.waitForConditionPollInterval = 9;\n\n      Nocks.url()\n        .getUrl()\n        .getUrl()\n        .getUrl();\n\n      let expect = this.client.api.expect.url().to.not.match(/localhost/);\n      assert.ok(expect.assertion.message.startsWith('Expected current url to'));\n\n      return this.client.start(function() {\n        strictEqual(expect.assertion.expected, 'not match \\'/localhost/\\'');\n        strictEqual(expect.assertion.actual, 'http://localhost');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'http://localhost');\n        strictEqual(expect.assertion.passed, false);\n        assert.deepStrictEqual(expect.assertion.messageParts[0], ' not match: \"/localhost/\"');\n        assert.ok(expect.assertion.message.startsWith('Expected current url to not match: \"/localhost/\"'));\n      });\n    });\n\n    it('to  match - throws exception on invalid regex', function() {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.url().getUrl();\n\n      let expect = this.client.api.expect.url();\n      assert.throws(function() {\n        expect.matches('');\n      }.bind(this));\n\n      return this.client.start();\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectValue.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst {strictEqual} = assert;\n\ndescribe('expect.value', function () {\n  describe('with backwards compat mode', function () {\n    beforeEach(function (done) {\n      ExpectGlobals.beforeEach.call(this, {\n        output: false,\n        silent: false,\n        backwards_compatibility_mode: true\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function (done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('to have value equal to [PASSED]', function () {\n      Nocks.elementFound().value('hp vasq');\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('hp vasq');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value equal to: \"hp vasq\"'));\n      });\n    });\n\n    it('to have value equal to [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .value('hp vasq')\n        .value('hp vasq')\n        .value('hp vasq');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('vasq');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'equal to \\'vasq\\'');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.actual, 'hp vasq');\n        strictEqual(expect.assertion.resultValue, 'hp vasq');\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.messageParts[0], ' equal to: \"vasq\"');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value equal to: \"vasq\"'));\n      });\n    });\n\n    it('to have value equals [FAILED] - value attribute not found', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .value(null)\n        .value(null)\n        .value(null);\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('xx');\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'equal to \\'xx\\'');\n        strictEqual(expect.assertion.actual, null);\n        strictEqual(expect.assertion.resultValue, null);\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.message, `Expected element <#weblogin> to have value equal to: \"xx\" - value attribute was not found - expected \"equal to 'xx'\" but got: \"null\" (${expect.assertion.elapsedTime}ms)`);\n      });\n    });\n\n    it('value toEqual - stale element error', function () {\n      this.client.api.globals.waitForConditionTimeout = 250;\n      this.client.api.globals.waitForConditionPollInterval = 100;\n\n      Nocks\n        .elementFound()\n        .elementStateError({\n          error: 'stale element reference',\n          url: '/wd/hub/session/1352110219202/element/0/property/value',\n          method: 'get'\n        })\n        .elementNotFound()\n        .elementNotFound()\n        .elementNotFound()\n        .elementNotFound();\n\n      let expect = this.client.api.expect.element('#weblogin').value.equal('xx');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.selector, '#weblogin');\n        strictEqual(expect.assertion.negate, false);\n        assert.ok(expect.assertion.retries >= 2, expect.assertion.retries + ' retries.');\n        strictEqual(expect.assertion.resultValue, null);\n        strictEqual(expect.assertion.actual, 'not present');\n        strictEqual(expect.assertion.passed, false);\n      });\n    });\n  });\n\n  describe('without backwards compat', function () {\n    beforeEach(function (done) {\n      ExpectGlobals.beforeEach.call(this, {\n        output: false,\n        silent: false\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function (done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('to have value equal to [PASSED]', function () {\n      Nocks.elementFound().value('hp vasq');\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('hp vasq');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value equal to: \"hp vasq\"'));\n      });\n    });\n\n    it('to have value which equals [PASSED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .value('hp vasq')\n        .value('hp vasq')\n        .value('hp vasq');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.which.equals('hp vasq');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 40);\n        strictEqual(expect.assertion.passed, true);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value which equals: \"hp vasq\"'));\n      });\n    });\n\n    it('to have value equal to [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .value('hp vasq')\n        .value('hp vasq')\n        .value('hp vasq');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('vasq');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'equal to \\'vasq\\'');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.actual, 'hp vasq');\n        strictEqual(expect.assertion.resultValue, 'hp vasq');\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.messageParts[0], ' equal to: \"vasq\"');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value equal to: \"vasq\"'));\n      });\n    });\n\n    it('to have value NOT equal to [PASSED]', function () {\n      Nocks.elementFound().value('hp vasq');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.not.equal('xx');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.resultValue, 'hp vasq');\n        strictEqual(expect.assertion.messageParts[0], ' not equal to: \"xx\"');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value not equal to: \"xx\"'));\n      });\n    });\n\n    it('to have value NOT equal to [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .value('hp vasq')\n        .value('hp vasq')\n        .value('hp vasq');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.not.equal('hp vasq');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'not equal to \\'hp vasq\\'');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.actual, 'hp vasq');\n        strictEqual(expect.assertion.resultValue, 'hp vasq');\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.message, `Expected element <#weblogin> to have value not equal to: \"hp vasq\" - expected \"not equal to 'hp vasq'\" but got: \"hp vasq\" (${expect.assertion.elapsedTime}ms)`);\n      });\n    });\n\n    it('to have value equal with waitFor [PASSED]', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks\n        .elementFound()\n        .value(null)\n        .value('hp vasq');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('hp vasq').before(110);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 110);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.retries, 1);\n        strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have value equal to: \"hp vasq\" in 110ms (' + expect.assertion.elapsedTime + 'ms)');\n      });\n    });\n\n    it('to have value equal and waitFor [FAILED] - value not equal', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementFound().value('xx', 3);\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('hp vasq').before(110);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 110);\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.retries >= 1);\n        assert.ok(expect.assertion.elapsedTime >= 110);\n        strictEqual(expect.assertion.expected, 'equal to \\'hp vasq\\'');\n        //strictEqual(expect.assertion.actual, 'xx');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value equal to: \"hp vasq\" in 110ms'));\n      });\n    });\n\n    it('to have value not equal to [PASSED]', function () {\n      Nocks.elementFound().value('xx');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.not.equal('vasq');\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'not equal to \\'vasq\\'');\n        strictEqual(expect.assertion.actual, 'xx');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'xx');\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.messageParts[0], ' not equal to: \"vasq\"');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value not equal to: \"vasq\"'));\n      });\n    });\n\n    it('to have value not equal to [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .value('xx')\n        .value('xx')\n        .value('xx');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.not.equal('xx');\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'not equal to \\'xx\\'');\n        strictEqual(expect.assertion.actual, 'xx');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'xx');\n        strictEqual(expect.assertion.passed, false);\n      });\n    });\n\n    it('to have value not contains [PASSED]', function () {\n      Nocks.elementFound().value('xx');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.not.contains('vasq');\n\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'not contain \\'vasq\\'');\n        strictEqual(expect.assertion.actual, 'xx');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'xx');\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.messageParts[0], ' not contain: \"vasq\"');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value not contain: \"vasq\"'));\n      });\n    });\n\n    it('to have value contains [PASSED]', function () {\n      Nocks.elementFound().value('vasq');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.which.contains('vasq');\n\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'contains \\'vasq\\'');\n        strictEqual(expect.assertion.actual, 'vasq');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.resultValue, 'vasq');\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.messageParts[0], ' which ');\n        strictEqual(expect.assertion.messageParts[1], 'contains: \"vasq\"');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value which contains: \"vasq\"'));\n      });\n    });\n\n    it('to have value not contains [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .value('xx')\n        .value('xx')\n        .value('xx');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.not.contains('xx');\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'not contain \\'xx\\'');\n        strictEqual(expect.assertion.actual, 'xx');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'xx');\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.message, `Expected element <#weblogin> to have value not contain: \"xx\" - expected \"not contain 'xx'\" but got: \"xx\" (${expect.assertion.elapsedTime}ms)`);\n      });\n    });\n\n    it('to have value equals [FAILED] - value attribute not found', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .value(null)\n        .value(null)\n        .value(null);\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('xx');\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'equal to \\'xx\\'');\n        strictEqual(expect.assertion.actual, null);\n        strictEqual(expect.assertion.resultValue, null);\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.message, `Expected element <#weblogin> to have value equal to: \"xx\" - value attribute was not found - expected \"equal to 'xx'\" but got: \"null\" (${expect.assertion.elapsedTime}ms)`);\n      });\n    });\n\n    it('to have value not match [PASSED]', function () {\n      Nocks.elementFound().value('xx');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.not.match(/vasq/);\n\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'not match \\'/vasq/\\'');\n        strictEqual(expect.assertion.actual, 'xx');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'xx');\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.messageParts[0], ' not match: \"/vasq/\"');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value not match: \"/vasq/\"'));\n      });\n    });\n\n    it('to have value which matches [PASSED]', function () {\n      Nocks.elementFound().value('vasq');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.which.matches(/vasq/);\n\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'matches \\'/vasq/\\'');\n        strictEqual(expect.assertion.actual, 'vasq');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.resultValue, 'vasq');\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.messageParts[0], ' which ');\n        strictEqual(expect.assertion.messageParts[1], 'matches: \"/vasq/\"');\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value which matches: \"/vasq/\"'));\n      });\n    });\n\n    it('to have value not match [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .value('xx')\n        .value('xx')\n        .value('xx');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.not.match(/xx/);\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'not match \\'/xx/\\'');\n        strictEqual(expect.assertion.actual, 'xx');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.resultValue, 'xx');\n        strictEqual(expect.assertion.passed, false);\n      });\n    });\n\n    it('to have value equal to - element not found', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks\n        .elementNotFound()\n        .elementNotFound()\n        .elementNotFound()\n        .elementNotFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('vasq');\n      assert.ok(expect.assertion.message.startsWith('Expected element %s to have value'));\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'equal to \\'vasq\\'');\n        strictEqual(expect.assertion.actual, 'not present');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.resultValue, null);\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.message, `Expected element <#weblogin> to have value equal to: \"vasq\" - element was not found - expected \"equal to 'vasq'\" but got: \"not present\" (${expect.assertion.elapsedTime}ms)`);\n      });\n    });\n\n    it('to have value which contains - element not found', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks\n        .elementNotFound()\n        .elementNotFound()\n        .elementNotFound()\n        .elementNotFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.which.contains('vasq');\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'contains \\'vasq\\'');\n        strictEqual(expect.assertion.actual, 'not present');\n        strictEqual(expect.assertion.passed, false);\n      });\n    });\n\n    it('to have value match - element not found', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks\n        .elementNotFound()\n        .elementNotFound()\n        .elementNotFound()\n        .elementNotFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.which.matches(/vasq$/);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.expected, 'matches \\'/vasq$/\\'');\n        strictEqual(expect.assertion.actual, 'not present');\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.message, `Expected element <#weblogin> to have value which matches: \"/vasq$/\" - element was not found - expected \"matches '/vasq$/'\" but got: \"not present\" (${expect.assertion.elapsedTime}ms)`);\n      });\n    });\n\n    it('to have value equal to with waitFor - element not found', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('hp vasq').before(60);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 60);\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value equal to: \"hp vasq\" in 60ms - element was not found'));\n      });\n    });\n\n    it('to have value equal with waitFor - element found on retry', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n      Nocks.elementNotFound().elementFound().value('hp vasq');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('hp vasq').before(110);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 110);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.message, 'Expected element <#weblogin> to have value equal to: \"hp vasq\" in 110ms (' + expect.assertion.elapsedTime + 'ms)');\n      });\n    });\n\n    it('to have value match - throws exception on invalid regex', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .value('xx')\n        .value('xx')\n        .value('xx');\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value;\n      assert.throws(function () {\n        expect.which.matches('');\n      }.bind(this));\n\n      return this.client.start();\n    });\n\n    it('to have value equal and waitFor [FAILED] - value not found', function () {\n      this.client.api.globals.waitForConditionPollInterval = 100;\n      Nocks.elementFound();\n\n      let expect = this.client.api.expect.element('#weblogin').to.have.value.equal('hp vasq').before(250);\n\n      Nocks.elementFound().value('xx', 4);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 250);\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.retries > 1);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to have value equal to: \"hp vasq\" in 250ms'));\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect/testExpectVisible.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\nconst {strictEqual} = assert;\n\ndescribe('expect.visible', function () {\n  describe('with backwards compat mode', function () {\n    beforeEach(function (done) {\n      ExpectGlobals.beforeEach.call(this, {\n        backwards_compatibility_mode: true\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function (done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    it('to be visible [PASSED]', function () {\n      Nocks.elementFound().visible();\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.selector, '#weblogin');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.resultValue, true);\n        strictEqual(expect.assertion.message, `Expected element <#weblogin> to be visible (${expect.assertion.elapsedTime}ms)`);\n        strictEqual(expect.assertion.messageParts.length, 1);\n      });\n    });\n\n    it('to be visible with waitFor [FAILED]', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementFound().notVisible(3);\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible.before(60);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 60);\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be visible in 60ms'));\n      });\n    });\n  });\n\n  describe('without backwards compat', function () {\n    beforeEach(function (done) {\n      ExpectGlobals.beforeEach.call(this, {\n        output: false,\n        silent: false,\n        webdriver: {\n          timeout_options: {\n            retry_attempts: 0\n          }\n        }\n      }, () => {\n        this.client.api.globals.abortOnAssertionFailure = false;\n        done();\n      });\n    });\n\n    afterEach(function (done) {\n      Nocks.cleanAll();\n      ExpectGlobals.afterEach.call(this, done);\n    });\n\n    const {runExpectAssertion} = ExpectGlobals;\n\n    it('to be visible [PASSED]', function () {\n      Nocks.elementFound().visible();\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.selector, '#weblogin');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.resultValue, true);\n        strictEqual(expect.assertion.message, `Expected element <#weblogin> to be visible (${expect.assertion.elapsedTime}ms)`);\n        strictEqual(expect.assertion.messageParts.length, 1);\n      });\n    });\n\n    it('to be visible [PASSED] -- appium', function () {\n      Nocks.appiumElementFound().appiumElementVisible();\n\n      // Make appium client\n      this.client.api.options.selenium.use_appium = true;\n      strictEqual(this.client.api.isAppiumClient(), true);\n\n      const expect = this.client.api.expect.element({selector: 'com.app:id/web-login', locateStrategy: 'id'}).to.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.selector, 'com.app:id/web-login');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.resultValue, true);\n        strictEqual(expect.assertion.message, `Expected element <com.app:id/web-login> to be visible (${expect.assertion.elapsedTime}ms)`);\n        strictEqual(expect.assertion.messageParts.length, 1);\n      });\n    });\n\n    it('to be visible with waitFor [PASSED]', function () {\n      Nocks.elementFound().visible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible.before(100);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 100);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.message, 'Expected element <#weblogin> to be visible in 100ms (' + expect.assertion.elapsedTime + 'ms)');\n      });\n    });\n\n    it('to be visible with waitFor [FAILED]', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementFound().notVisible(3);\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible.before(60);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 60);\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be visible in 60ms'));\n      });\n    });\n\n    it('to be visible [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .notVisible()\n        .notVisible()\n        .notVisible();\n\n      return runExpectAssertion.call(this, {\n        fn: expect => expect.to.be.visible,\n        assertion({selector, negate, waitForMs, expected, passed, actual, resultValue, message, messageParts, elapsedTime}) {\n          strictEqual(selector, '#weblogin');\n          strictEqual(negate, false);\n          strictEqual(passed, false);\n          strictEqual(waitForMs, 40);\n          strictEqual(resultValue, false);\n          strictEqual(actual, 'not visible');\n          strictEqual(expected, 'visible');\n          strictEqual(message, `Expected element <#weblogin> to be visible - expected \"visible\" but got: \"not visible\" (${elapsedTime}ms)`);\n          strictEqual(messageParts.length, 2, messageParts);\n        }\n      });\n    });\n\n    it('to not be visible [PASSED]', function () {\n      Nocks.elementFound().notVisible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.not.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.selector, '#weblogin');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.expected, 'not visible');\n        strictEqual(expect.assertion.actual, 'not visible');\n        strictEqual(expect.assertion.resultValue, false);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be visible'));\n        strictEqual(expect.assertion.messageParts.length, 1);\n      });\n    });\n\n    it('to not be visible [FAILED]', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks.elementFound()\n        .visible()\n        .visible()\n        .visible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.not.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.selector, '#weblogin');\n        strictEqual(expect.assertion.negate, true);\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.expected, 'not visible');\n        strictEqual(expect.assertion.actual, 'visible');\n        strictEqual(expect.assertion.resultValue, true);\n        strictEqual(expect.assertion.message, `Expected element <#weblogin> to not be visible - expected \"not visible\" but got: \"visible\" (${expect.assertion.elapsedTime}ms)`);\n      });\n    });\n\n    it('to be visible - element not found', function () {\n      this.client.api.globals.waitForConditionTimeout = 40;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks\n        .elementNotFound()\n        .elementNotFound()\n        .elementNotFound()\n        .elementNotFound();\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.selector, '#weblogin');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.waitForMs, 40);\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.expected, 'visible');\n        strictEqual(expect.assertion.actual, 'not found');\n        strictEqual(expect.assertion.resultValue, null);\n        strictEqual(expect.assertion.message, `Expected element <#weblogin> to be visible - element was not found - expected \"visible\" but got: \"not found\" (${expect.assertion.elapsedTime}ms)`);\n      });\n    });\n\n    it('to be visible - stale element error followed by success', function () {\n      this.client.api.globals.waitForConditionTimeout = 500;\n      this.client.api.globals.waitForConditionPollInterval = 100;\n\n      Nocks\n        .elementFound()\n        .elementStateError({error: 'stale element reference'})\n        .elementFound()\n        .visible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.selector, '#weblogin');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.retries, 1);\n        strictEqual(expect.assertion.resultValue, true);\n        strictEqual(expect.assertion.passed, true);\n      });\n    });\n\n    it('to be visible - generic element error followed by success', function () {\n      this.client.api.globals.waitForConditionTimeout = 500;\n      this.client.api.globals.waitForConditionPollInterval = 100;\n\n      Nocks\n        .elementFound()\n        .elementStateError({error: ''})\n        .elementFound()\n        .visible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.selector, '#weblogin');\n        strictEqual(expect.assertion.negate, false);\n        strictEqual(expect.assertion.retries, 1);\n        strictEqual(expect.assertion.resultValue, true);\n        strictEqual(expect.assertion.passed, true);\n      });\n    });\n\n\n    it('to be visible - element not interactable error', function () {\n      this.client.api.globals.waitForConditionTimeout = 100;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks\n        .elementFound()\n        .elementStateError({\n          error: 'element not interactable'\n        })\n        .elementFound()\n        .visible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.retries, 1);\n        strictEqual(expect.assertion.resultValue, true);\n        strictEqual(expect.assertion.passed, true);\n      });\n    });\n\n    it('to be visible - invalid element state error', function () {\n      this.client.api.globals.waitForConditionTimeout = 100;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks\n        .elementFound()\n        .elementStateError({\n          error: 'invalid element state'\n        })\n        .elementFound()\n        .visible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.retries, 1);\n        strictEqual(expect.assertion.resultValue, true);\n        strictEqual(expect.assertion.passed, true);\n      });\n    });\n\n    it('to be visible - element click intercepted error', function () {\n      this.client.api.globals.waitForConditionTimeout = 100;\n      this.client.api.globals.waitForConditionPollInterval = 20;\n\n      Nocks\n        .elementFound()\n        .elementStateError({\n          error: 'element click intercepted'\n        })\n        .elementFound()\n        .visible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.retries, 1);\n        strictEqual(expect.assertion.resultValue, true);\n        strictEqual(expect.assertion.passed, true);\n      });\n    });\n\n    it('to be visible - session not created error', function () {\n      this.client.api.globals.waitForConditionTimeout = 250;\n      this.client.api.globals.waitForConditionPollInterval = 100;\n\n      Nocks\n        .elementFound()\n        .elementStateError({\n          error: 'session not created',\n          code: 500,\n          times: 5\n        });\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        assert.ok(expect.assertion.retries >= 2);\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.resultValue, null);\n        strictEqual(expect.assertion.actual, '[SessionNotCreatedError]');\n      });\n    });\n\n    it('to be visible - unknown error', function () {\n      this.client.api.globals.waitForConditionTimeout = 200;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks\n        .elementFound()\n        .elementStateError({\n          error: '',\n          code: 400,\n          times: 5\n        });\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        assert.ok(expect.assertion.retries >= 2);\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.resultValue, null);\n        strictEqual(expect.assertion.actual, 'not visible');\n      });\n    });\n\n    it('to be visible - invalid json response', function() {\n      this.client.api.globals.waitForConditionTimeout = 250;\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks\n        .elementFound()\n        .elementStateError({\n          error: '',\n          code: 500,\n          times: 15,\n          reply: '<html></html>'\n        });\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible;\n\n      return this.client.start(function () {\n        assert.ok(expect.assertion.retries >= 2);\n        strictEqual(expect.assertion.passed, false);\n        strictEqual(expect.assertion.resultValue, null);\n        strictEqual(expect.assertion.actual, '[WebDriverError]');\n      });\n    });\n\n    it('to not be visible with waitFor [FAILED]', function () {\n      this.client.api.globals.waitForConditionPollInterval = 15;\n\n      Nocks.elementFound().visible().visible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.not.be.visible.before(25);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 25);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to not be visible in 25ms'));\n        strictEqual(expect.assertion.passed, false);\n      });\n    });\n\n    it('to not be visible with waitFor [PASSED] - element not visible on retry', function () {\n      this.client.api.globals.waitForConditionPollInterval = 100;\n\n      Nocks.elementFound().visible().notVisible().notVisible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.not.be.visible.before(130);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 130);\n        strictEqual(expect.assertion.message.indexOf('Expected element <#weblogin> to not be visible in 130ms'), 0);\n        strictEqual(expect.assertion.passed, true, 'Assertion has passed');\n      });\n    });\n\n    it('to be visible with waitFor - element not found', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementNotFound().elementNotFound().elementNotFound();\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible.before(60);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 60);\n        strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.startsWith('Expected element <#weblogin> to be visible in 60ms - element was not found'));\n      });\n    });\n\n    it('to be visible with waitFor - element found on retry', function () {\n      this.client.api.globals.waitForConditionPollInterval = 50;\n\n      Nocks.elementNotFound().elementFound().visible();\n\n      const expect = this.client.api.expect.element('#weblogin').to.be.visible.before(60);\n\n      return this.client.start(function () {\n        strictEqual(expect.assertion.waitForMs, 60);\n        strictEqual(expect.assertion.passed, true);\n        strictEqual(expect.assertion.message, 'Expected element <#weblogin> to be visible in 60ms (' + expect.assertion.elapsedTime + 'ms)');\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect-global/testElementAttribute.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\n\ndescribe('expect(element.attribute)', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      silent: true,\n      output: false\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = true;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('to have attribute which matches [PASSED]', function(done) {\n    this.client.api.globals.waitForConditionTimeout = 0;\n\n    Nocks\n      .elementFound()\n      .attributeValueSync('vasq');\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.attribute('class')).which.matches(/vasq/);\n\n    this.client.start(done);\n  });\n\n  it('to have attribute equals [FAILED]', function(done) {\n    this.client.api.globals.waitForConditionTimeout = 0;\n\n    Nocks\n      .elementFound()\n      .attributeValueSync('vasq');\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.getAttribute('class')).to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected \\'vasq\\' to equal \\'qq\\''));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('to have attribute equals [FAILED] - custom message', function(done) {\n    this.client.api.globals.waitForConditionTimeout = 0;\n\n    Nocks\n      .elementFound()\n      .attributeValueSync('vasq');\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.attribute('class'), 'custom assert message').to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('custom assert message'));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('to have attribute which deep equals [PASSED]', function(done) {\n    this.client.api.globals.waitForConditionTimeout = 0;\n\n    Nocks\n      .elementFound()\n      .attributeValueSync(['class-one', 'class-two']);\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.attribute('class')).to.contain('class-one').and.contain('class-two');\n  \n    this.client.start(done);\n  });\n\n\n  it('to have attribute which contains and custom waitFor [FAILED] - element not found', function(done) {\n    Nocks\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    this.client.api.globals.abortOnAssertionFailure = true;\n    this.client.api.globals.waitForConditionTimeout = 65;\n    this.client.api.globals.waitForConditionPollInterval = 55;\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.attribute('class')).to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal \\'qq\\''));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('to have attribute contains [FAILED] - attribute not found', function(done) {\n    Nocks\n      .elementFound()\n      .attributeValueSync()\n      .attributeValueSync()\n      .attributeValueSync();\n\n    this.client.api.globals.abortOnAssertionFailure = false;\n    this.client.api.globals.waitForConditionTimeout = 0;\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.attribute('class')).to.equal('qq');\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal \\'qq\\''));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect-global/testElementCss.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\n\ndescribe('expect(element.css)', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      silent: true,\n      output: false\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = true;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('to have css which matches [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .cssProperty('vasq');\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.css('display')).which.matches(/vasq/);\n\n    this.client.start(done);\n  });\n\n  it('to have css equals [FAILED]', function(done) {\n    Nocks\n      .elementFound()\n      .cssProperty('vasq');\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.getCssValue('display')).to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected \\'vasq\\' to equal \\'qq\\''));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('to have css equals [FAILED] - custom message', function(done) {\n    Nocks\n      .elementFound()\n      .cssProperty('vasq');\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.css('display'), 'custom assert message').to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('custom assert message'));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('to have css which deep equals [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .cssProperty(['class-one', 'class-two']);\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.css('display')).to.contain('class-one').and.contain('class-two');\n  \n    this.client.start(done);\n  });\n\n  it('to have css which contains [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .cssProperty(['class-one', 'class-two']);\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.css('display').contain('class-one');\n\n    assert.strictEqual(expect.assertion.message, 'Expected element %s to have css property \"display\"');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'contain \\'class-one\\'');\n      assert.deepStrictEqual(expect.assertion.actual, ['class-one', 'class-two']);\n      assert.strictEqual(expect.assertion.negate, false);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have css which contains and custom waitFor [FAILED] - element not found', function(done) {\n    Nocks\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    this.client.api.globals.abortOnAssertionFailure = true;\n    this.client.api.globals.waitForConditionTimeout = 65;\n    this.client.api.globals.waitForConditionPollInterval = 55;\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.css('display')).to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal \\'qq\\''));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('to have css contains [FAILED] - css not found', function(done) {\n    Nocks\n      .elementFound()\n      .cssProperty()\n      .cssProperty()\n      .cssProperty();\n\n    this.client.api.globals.abortOnAssertionFailure = false;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    this.client.api.globals.waitForConditionTimeout = 25;\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.css('display')).to.equal('qq');\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal \\'qq\\''));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect-global/testElementIsDisplayed.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\n\ndescribe('expect(element.attribute)', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      silent: true,\n      output: false\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = true;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('is displayed property which matches [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .visible();\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.isDisplayed()).which.matches(/true/);\n\n    this.client.start(done);\n  });\n\n  it('is displayed property equals [FAILED]', function(done) {\n    Nocks\n      .elementFound()\n      .visible();\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.isDisplayed()).to.equal(false);\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected true to equal false'));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('is displayed property equals [FAILED] - custom message', function(done) {\n    Nocks\n      .elementFound()\n      .visible();\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.isDisplayed(), 'custom assert message').to.equal(false);\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('custom assert message'));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('is displayed property which contains and custom waitFor [FAILED] - element not found', function(done) {\n    Nocks\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    this.client.api.globals.abortOnAssertionFailure = true;\n    this.client.api.globals.waitForConditionTimeout = 65;\n    this.client.api.globals.waitForConditionPollInterval = 55;\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.text()).to.equal(false);\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal false'));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect-global/testElementIsEnabled.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\n\ndescribe('expect(element.attribute)', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      silent: true,\n      output: false\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = true;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('is displayed property which matches [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .enabled();\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.isEnabled()).which.matches(/true/);\n\n    this.client.start(done);\n  });\n\n  it('is displayed property equals [FAILED]', function(done) {\n    Nocks\n      .elementFound()\n      .enabled();\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.isEnabled()).to.equal(false);\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected true to equal false'));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('is displayed property equals [FAILED] - custom message', function(done) {\n    Nocks\n      .elementFound()\n      .enabled();\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.isEnabled(), 'custom assert message').to.equal(false);\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('custom assert message'));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('is displayed property which contains and custom waitFor [FAILED] - element not found', function(done) {\n    Nocks\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    this.client.api.globals.abortOnAssertionFailure = true;\n    this.client.api.globals.waitForConditionTimeout = 65;\n    this.client.api.globals.waitForConditionPollInterval = 55;\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.text()).to.equal(false);\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal false'));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect-global/testElementIsSelected.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\n\ndescribe('expect(element.attribute)', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      silent: true,\n      output: false\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = true;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('is selected property which matches [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .selected();\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.isSelected()).which.matches(/true/);\n\n    this.client.start(done);\n  });\n\n  it('is selected property equals [FAILED]', function(done) {\n    Nocks\n      .elementFound()\n      .selected();\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.isSelected()).to.equal(false);\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected true to equal false'));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('is selected property equals [FAILED] - custom message', function(done) {\n    Nocks\n      .elementFound()\n      .selected();\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.isSelected(), 'custom assert message').to.equal(false);\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('custom assert message'));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('is selected property which contains and custom waitFor [FAILED] - element not found', function(done) {\n    Nocks\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    this.client.api.globals.abortOnAssertionFailure = true;\n    this.client.api.globals.waitForConditionTimeout = 65;\n    this.client.api.globals.waitForConditionPollInterval = 55;\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.isSelected()).to.equal(false);\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal false'));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect-global/testElementProperty.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\n\ndescribe('expect(element.property)', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      silent: true,\n      output: false\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = true;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('to have property which matches [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue('vasq');\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.property('className')).which.matches(/vasq/);\n\n    this.client.start(done);\n  });\n\n  it('to have property equals [FAILED]', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue('vasq');\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.getProperty('className')).to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected \\'vasq\\' to equal \\'qq\\''));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('to have property equals [FAILED] - custom message', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue('vasq');\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.property('className'), 'custom assert message').to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('custom assert message'));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('to have property which deep equals [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue(['class-one', 'class-two'], 'classList');\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.property('classList')).to.contain('class-one').and.contain('class-two');\n  \n    this.client.start(done);\n  });\n\n  it('to have property which contains [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue(['class-one', 'class-two'], 'classList');\n\n    let expect = this.client.api.expect.element('#weblogin').to.have.property('classList').contain('class-one');\n\n    assert.strictEqual(expect.assertion.message, 'Expected element %s to have dom property \"classList\"');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'contain \\'class-one\\'');\n      assert.deepStrictEqual(expect.assertion.actual, ['class-one', 'class-two']);\n      assert.strictEqual(expect.assertion.negate, false);\n    });\n\n    this.client.start(done);\n  });\n\n  it('to have property which contains and custom waitFor [FAILED] - element not found', function(done) {\n    Nocks\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    this.client.api.globals.abortOnAssertionFailure = true;\n    this.client.api.globals.waitForConditionTimeout = 65;\n    this.client.api.globals.waitForConditionPollInterval = 55;\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.property('className')).to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal \\'qq\\''));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('to have property contains [FAILED] - property not found', function(done) {\n    Nocks\n      .elementFound()\n      .propertyValue(null, 'className')\n      .propertyValue(null, 'className')\n      .propertyValue(null, 'className');\n\n    this.client.api.globals.abortOnAssertionFailure = false;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    this.client.api.globals.waitForConditionTimeout = 25;\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.property('className')).to.equal('qq');\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal \\'qq\\''));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/expect-global/testElementText.js",
    "content": "const assert = require('assert');\nconst Nocks = require('../../../lib/nocks.js');\nconst ExpectGlobals = require('../../../lib/globals/expect.js');\n\ndescribe('expect(element.property)', function() {\n  beforeEach(function(done) {\n    ExpectGlobals.beforeEach.call(this, {\n      silent: true,\n      output: false\n    }, () => {\n      this.client.api.globals.abortOnAssertionFailure = true;\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    ExpectGlobals.afterEach.call(this, done);\n  });\n\n  it('text to property which matches [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .text('vasq');\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.text()).to.match(/vasq/);\n\n    this.client.start(done);\n  });\n\n  it('text to property equals [FAILED]', function(done) {\n    Nocks\n      .elementFound()\n      .text('vasq');\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.getText()).to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected \\'vasq\\' to equal \\'qq\\''));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('text to property equals [FAILED] - custom message', function(done) {\n    Nocks\n      .elementFound()\n      .text('vasq');\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.text(), 'custom assert message').to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('custom assert message'));\n        done();\n      } catch (err){\n        done(err);\n      }\n    });\n  });\n\n  it('text to property which deep equals [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .text(['class-one', 'class-two']);\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.text()).to.contain('class-one').and.contain('class-two');\n  \n    this.client.start(done);\n  });\n\n  it('text to property which contains [PASSED]', function(done) {\n    Nocks\n      .elementFound()\n      .text(['class-one', 'class-two']);\n\n    let expect = this.client.api.expect.element('#weblogin').text.to.contain('class-one');\n\n    assert.strictEqual(expect.assertion.message, 'Expected element %s text to');\n    this.client.api.perform(function() {\n      assert.strictEqual(expect.assertion.expected, 'contain \\'class-one\\'');\n      assert.deepStrictEqual(expect.assertion.actual, ['class-one', 'class-two']);\n      assert.strictEqual(expect.assertion.negate, false);\n    });\n\n    this.client.start(done);\n  });\n\n  it('text to property which contains and custom waitFor [FAILED] - element not found', function(done) {\n    Nocks\n      .elementNotFound()\n      .elementNotFound()\n      .elementNotFound();\n\n    this.client.api.globals.abortOnAssertionFailure = true;\n    this.client.api.globals.waitForConditionTimeout = 65;\n    this.client.api.globals.waitForConditionPollInterval = 55;\n\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.text()).to.equal('qq');\n\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal \\'qq\\''));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('text to property contains [FAILED] - text not found', function(done) {\n    Nocks\n      .elementFound()\n      .text()\n      .text()\n      .text();\n\n    this.client.api.globals.abortOnAssertionFailure = false;\n    this.client.api.globals.waitForConditionPollInterval = 20;\n    this.client.api.globals.waitForConditionTimeout = 25;\n    const weblogin = this.client.api.createElement('#weblogin');\n    this.client.api.expect(weblogin.text()).to.equal('qq');\n    this.client.start((error)=>{\n      try {\n        assert.ok(error);\n        assert.strictEqual(error.name, 'NightwatchAssertError');\n        assert.ok(error.message.startsWith('expected null to equal \\'qq\\''));\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testActivity.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('Android activity commands', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testStartActivity with correct options', function() {\n    const opts = {\n      appPackage: 'org.wikipedia',\n      appActivity: 'org.wikipedia.main.MainActivity',\n      appWaitActivity: 'org.wikipedia.onboarding.InitialOnboardingActivity'\n    };\n\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/start_activity');\n        assert.deepStrictEqual(opts.data, {\n          appPackage: 'org.wikipedia',\n          appActivity: 'org.wikipedia.main.MainActivity',\n          appWaitActivity: 'org.wikipedia.onboarding.InitialOnboardingActivity'\n        });\n      },\n      commandName: 'appium.startActivity',\n      args: [opts]\n    });\n  });\n\n  it('testStartActivity with no options', function() {\n    return Globals.protocolTest({\n      commandName: 'appium.startActivity',\n      args: []\n    }).catch(err => {\n      return err;\n    }).then((result) => {\n      assert.ok(result instanceof Error);\n      assert.strictEqual(result.message.includes('Please provide both appPackage and appActivity options while using startActivity.'), true);\n    });\n  });\n\n  it('testGetCurrentActivity', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/current_activity');\n      },\n      commandName: 'appium.getCurrentActivity',\n      args: []\n    });\n  });\n\n  it('testGetCurrentPackage', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/current_package');\n      },\n      commandName: 'appium.getCurrentPackage',\n      args: []\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testAlerts.js",
    "content": "const assert = require('assert');\n\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('alert commands', function () {\n\n  before(function () {\n    Globals.protocolBefore({\n      backwards_compatibility_mode: true\n    });\n  });\n\n  it('testAcceptAlert', function (done) {\n    Globals.protocolTest({\n      commandName: 'acceptAlert',\n      assertion() {\n      }\n    }).then((result) => {\n      assert.strictEqual(result.value, null);\n      assert.strictEqual(result.status, 0);\n    }).catch(err => {\n      return err;\n    }).then(err => {\n      done(err);\n    });\n  });\n\n  it('testDismissAlert', function (done) {\n    Globals.protocolTest({\n      assertion: function (opts) {\n      },\n      commandName: 'dismissAlert'\n    }).then((result) => {\n      assert.strictEqual(result.value, null);\n      assert.strictEqual(result.status, 0);\n    }).catch(err => {\n      return err;\n    }).then(err => {\n      done(err);\n    });\n  });\n\n  it('testGetAlertText', function (done) {\n    Globals.protocolTest({\n      assertion: function (text) {\n        try {\n          assert.strictEqual(text, 'alert text');\n          done();\n        } catch (err) {\n          done(err);\n        }\n      },\n      commandName: 'getAlertText'\n    });\n  });\n\n  it('testSetAlertText', function (done) {\n    let text = 'prompt text to set';\n\n    Globals.protocolTest({\n      assertion: function (value) {\n        assert.strictEqual(value, text);\n      },\n      commandName: 'setAlertText',\n      args: [text]\n    }).then((result) => {\n      assert.strictEqual(result.value, null);\n      assert.strictEqual(result.status, 0);\n    }).catch(err => {\n      return err;\n    }).then(err => {\n      done(err);\n    });\n  });\n\n  it('test alerts.accept()', function (done) {\n    Globals.protocolTest({\n      commandName: 'alerts.accept'\n    }).then((result) => {\n      assert.strictEqual(result.value, null);\n      assert.strictEqual(result.status, 0);\n    }).catch(err => {\n      return err;\n    }).then(err => {\n      done(err);\n    });\n  });\n\n  it('test alerts.dismiss()', function (done) {\n    Globals.protocolTest({\n      commandName: 'alerts.dismiss'\n    }).then((result) => {\n      assert.strictEqual(result.value, null);\n      assert.strictEqual(result.status, 0);\n    }).catch(err => {\n      return err;\n    }).then(err => {\n      done(err);\n    });\n  });\n\n  it('test alerts.getText()', function (done) {\n    Globals.protocolTest({\n      assertion: function (text) {\n        try {\n          assert.strictEqual(text, 'alert text');\n          done();\n        } catch (err) {\n          done(err);\n        }\n      },\n      commandName: 'alerts.getText'\n    });\n  });\n\n  it('test alerts.setText()', function (done) {\n    const text = 'prompt text to set';\n\n    Globals.protocolTest({\n      assertion: function (value) {\n        assert.strictEqual(value, text);\n      },\n      commandName: 'alerts.setText',\n      args: [text]\n    }).then((result) => {\n      assert.strictEqual(result.value, null);\n      assert.strictEqual(result.status, 0);\n    }).catch(err => {\n      return err;\n    }).then(err => {\n      done(err);\n    });\n  });\n\n  it('test alerts.setText() with error', function (done) {\n    const text = 2;\n\n    Globals.protocolTest({\n      assertion: function (value) {\n        assert.strictEqual(value, text);\n      },\n      commandName: 'alerts.setText',\n      args: [text]\n    }).catch(err => {\n      assert.strictEqual(\n        err.message,\n        'Error while running \"alerts.setText\" command: First argument passed to .alerts.setText() must be a string.'\n      );\n    }).catch(err => {\n      return err;\n    }).then(err => {\n      done(err);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testBrowserCommands.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('browser navigation commands', function () {\n  before(function () {\n    Globals.protocolBefore();\n  });\n\n  it('testRefresh', function (done) {\n    Globals.protocolTest({\n      assertion() {\n      },\n      commandName: 'refresh',\n      args: []\n    }).then(result => {\n      assert.strictEqual(result, null);\n      done();\n    }).catch(err => done(err));\n  });\n\n  it('testBack', function (done) {\n    Globals.protocolTest({\n      assertion: function (opts) {\n      },\n      commandName: 'back',\n      args: []\n    }).then(result => {\n      assert.strictEqual(result, null);\n      done();\n    }).catch(err => done(err));\n  });\n\n  it('testForward', function (done) {\n    Globals.protocolTest({\n      assertion: function (opts) {\n      },\n      commandName: 'forward',\n      args: []\n    }).then(result => {\n      assert.strictEqual(result, null);\n      done();\n    }).catch(err => done(err));\n  });\n\n  it('testNavigateTo', function (done) {\n    Globals.protocolTest({\n      assertion: function (opts) {\n        assert.strictEqual(opts.command, 'url');\n        assert.strictEqual(opts.url, 'https://test.com');\n      },\n      commandName: 'url',\n      args: ['https://test.com']\n    }).then(result => {\n      assert.strictEqual(result, null);\n      done();\n    }).catch(err => done(err));\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testChrome.js",
    "content": "const assert = require('assert');\n\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('Chrome API commands', function () {\n  before(function () {\n    Globals.protocolBefore();\n  });\n\n  it('testLaunchApp', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.command, 'launchApp');\n      },\n      commandName: 'chrome.launchApp',\n      args: ['1'],\n      browserDriver: 'chrome'\n    }).then((result) => {\n      assert.deepStrictEqual(result.value, null);\n    });\n  });\n\n  it('getNetworkConditions', function() {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.command, 'getNetworkConditions');\n      },\n      commandName: 'chrome.getNetworkConditions',\n      args: [],\n      browserDriver: 'chrome'\n    }).then((result) => {\n      assert.deepStrictEqual(result.value, {\n        download_throughput: 460800,\n        latency: 50000,\n        offline: false,\n        upload_throughput: 153600\n      });\n    });\n  });\n\n  it('setNetworkConditions', function() {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.command, 'setNetworkConditions');\n      },\n      commandName: 'chrome.setNetworkConditions',\n      args: [\n        {\n          offline: false,\n          latency: 50000,\n          download_throughput: 450 * 1024,\n          upload_throughput: 150 * 1024\n        }\n      ],\n      browserDriver: 'chrome'\n    }).then((result) => {\n      assert.strictEqual(result.value, null);\n    });\n  });\n\n  it('sendDevToolsCommand', function() {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.command, 'sendDevToolsCommand');\n        assert.strictEqual(opts.cmd, 'Browser.getVersion');\n        assert.deepStrictEqual(opts.params, {});\n      },\n      commandName: 'chrome.sendDevToolsCommand',\n      args: ['Browser.getVersion', {}],\n      browserDriver: 'chrome'\n    }).then((result) => {\n      assert.strictEqual(result.value, null);\n    });\n  });\n\n  it('sendAndGetDevToolsCommand', function() {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.command, 'sendAndGetDevToolsCommand');\n        assert.strictEqual(opts.cmd, 'Browser.getVersion');\n        assert.deepStrictEqual(opts.params, {});\n      },\n      commandName: 'chrome.sendAndGetDevToolsCommand',\n      args: ['Browser.getVersion', {}],\n      browserDriver: 'chrome'\n    })\n      .then((result) => {\n        assert.deepStrictEqual(\n          result.value.userAgent,\n          'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'\n        );\n        assert.strictEqual(result.value.product, 'Chrome/92.0.4515.159');\n      });\n  });\n\n  it('setDownloadPath', function() {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.command, 'setDownloadPath');\n        assert.strictEqual(opts.path, '/path/to/downloadFolder');\n      },\n      commandName: 'chrome.setDownloadPath',\n      args: ['/path/to/downloadFolder'],\n      browserDriver: 'chrome'\n    })\n      .then((result) => {\n        assert.strictEqual(result.value, null);\n      });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testContext.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('context commands', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testContexts', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.path, '/session/1352110219202/contexts');\n      },\n      commandName: 'contexts',\n      args: []\n    });\n  });\n\n  it('testCurrentContext', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.path, '/session/1352110219202/context');\n      },\n      commandName: 'currentContext',\n      args: []\n    });\n  });\n\n  it('testSetContext', function() {\n    let text = 'NATIVE';\n\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/context');\n        assert.deepStrictEqual(opts.data, {name: text});\n      },\n      commandName: 'setContext',\n      args: [text]\n    });\n  });\n\n  it('testGetContexts - appium', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.path, '/session/1352110219202/contexts');\n      },\n      commandName: 'appium.getContexts',\n      args: []\n    });\n  });\n\n  it('testGetContext - appium', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.path, '/session/1352110219202/context');\n      },\n      commandName: 'appium.getContext',\n      args: []\n    });\n  });\n\n  it('testSetContext - appium', function() {\n    let text = 'NATIVE';\n\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/context');\n        assert.deepStrictEqual(opts.data, {name: text});\n      },\n      commandName: 'appium.setContext',\n      args: [text]\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testCookies.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('cookie commands', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testCookieGet', function () {\n    return Globals.protocolTest({\n      assertion: function(cookie) {\n        assert.strictEqual(cookie, 'cookie-test');\n      },\n      commandName: 'cookie',\n      args: ['GET']\n    });\n  });\n\n  it('testCookiePost', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.deepStrictEqual(opts, {name: 'test_cookie'});\n      },\n      commandName: 'cookie',\n      args: ['POST', {name: 'test_cookie'}]\n    });\n  });\n\n  it('testCookieDeleteAll', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.deepStrictEqual(opts, {\n          command: 'deleteAllCookies'\n        });\n      },\n      commandName: 'cookie',\n      args: ['DELETE']\n    });\n  });\n\n  it('testCookieDeleteOne', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts, 'test_cookie');\n      },\n      commandName: 'cookie',\n      args: ['DELETE', 'test_cookie']\n    });\n  });\n\n  it('testCookieErrors', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {},\n      commandName: 'cookie',\n      args: ['POST']\n    }).catch(err => {\n      return err;\n    }).then(result => {\n      assert.ok(result instanceof Error);\n      assert.strictEqual(result.message, 'Error while running \"cookie\" command: POST requests to /cookie must include a cookie object parameter also.');\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testDoubleClick.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../lib/globals/commands-w3c.js');\n\ndescribe('client.doubleClick()', function() {\n  let callbackResult;\n\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .elementIdDoubleClick() - successful', function() {\n\n    this.client.transport.driver.actions = function() {\n      return {\n        doubleClick: function() {\n          return {\n            perform: function() {\n              return Promise.resolve();\n            }\n          };\n        }\n      };\n    };\n\n    this.client.api.elementIdDoubleClick(function callback(result) {\n      callbackResult = result;\n    });\n\n    return this.client.start(function() {\n      assert.ok(callbackResult, 'Result from callback is undefined');\n      assert.strictEqual(callbackResult.status, 0);\n      assert.strictEqual(callbackResult.value, null);\n    });\n  });\n\n  it('test .elementIdDoubleClick - failed', function() {\n\n    this.client.transport.driver.actions = function() {\n      return {\n        doubleClick: function() {\n          return {\n            perform: function() {\n              return Promise.reject(new Error('no such window'));\n            }\n          };\n        }\n      };\n    };\n\n    this.client.api.elementIdDoubleClick(function callback(result) {\n      callbackResult = result;\n    });\n\n    return this.client.start(function() {\n      assert.ok(callbackResult, 'Result from callback is undefined');\n      assert.strictEqual(callbackResult.status, -1);\n      assert.strictEqual(callbackResult.error.message, 'no such window');\n    });\n  });\n});"
  },
  {
    "path": "test/src/api/protocol/testElementCommands.js",
    "content": "const assert = require('assert');\nconst {By, WebElement} = require('selenium-webdriver');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('element actions', function () {\n  describe('.element() with backwards compat mode', function() {\n    before(function (done) {\n      Globals.protocolBefore({\n        backwards_compatibility_mode: true\n      }, done);\n    });\n\n    after((done) => Globals.protocolAfter(done));\n\n    it('testElement', function () {\n      return Globals.protocolTest({\n        assertion({locator, command}) {\n          assert.ok(locator instanceof By);\n          assert.strictEqual(locator.using, 'css selector');\n          assert.strictEqual(command, 'findElement');\n        },\n        commandName: 'element',\n        args: ['css selector', '#weblogin', function(result) {\n          assert.deepStrictEqual(result.value, {\n            'element-6066-11e4-a52e-4f735466cecf': '12345-6789'\n          });\n          assert.strictEqual(result.status, 0);\n        }]\n      });\n    });\n  });\n\n  describe('elements', function() {\n    const warn = console.warn;\n    before(function () {\n      Globals.protocolBefore();\n    });\n\n    afterEach(() => {\n      console.warn = warn;\n    });\n\n    after((done) => Globals.protocolAfter(done));\n\n    it('testMultipleElements', function () {\n      return Globals.protocolTest({\n        assertion({locator, command}) {\n          assert.ok(locator instanceof By);\n          assert.strictEqual(command, 'findElements');\n        },\n        commandName: 'elements',\n        args: ['id', '#weblogin', function({value, status}) {\n          assert.strictEqual(status, 0);\n          assert.deepStrictEqual(value, [{'element-6066-11e4-a52e-4f735466cecf': '12345-6789'}]);\n        }]\n      });\n    });\n\n    it('testMultipleElements with no results', function () {\n      return Globals.protocolTest({\n        commandName: 'elements',\n        args: ['id', '#weblogin', function({value, status, error}) {\n          assert.deepStrictEqual(value, []);\n        }],\n        mockDriverOverrides: {\n          findElements(locator) {\n            return [];\n          }\n        }\n      });\n    });\n\n    it('testElementIdElement', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.ok(args.id instanceof WebElement);\n          assert.strictEqual(command, 'findChildElement');\n        },\n        commandName: 'elementIdElement',\n        args: ['0', 'id', '#weblogin', function({value, status, elementId}) {\n          assert.strictEqual(status, 0);\n          assert.deepStrictEqual(value, {'element-6066-11e4-a52e-4f735466cecf': '6789-192111'});\n          assert.strictEqual(elementId, '6789-192111');\n        }]\n      });\n    });\n\n    it('testElementIdElement invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdElement',\n        args: [false, 'id', '#weblogin']\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdElement\" command: First argument passed to .elementIdElement() should be a web element ID string. Received boolean.');\n      });\n    });\n\n    it('testElementIdElementPlural', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.strictEqual(command, 'findChildElements');\n          assert.ok(args.id instanceof WebElement);\n        },\n        commandName: 'elementIdElements',\n        args: ['0', 'id', '#weblogin', function({value, status}) {\n          assert.strictEqual(status, 0);\n          assert.deepStrictEqual(value, [{'element-6066-11e4-a52e-4f735466cecf': '6789-192111'}]);\n        }]\n      });\n    });\n\n    it('testElementIdElementPlural invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdElements',\n        args: [false, 'id', '#weblogin']\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdElements\" command: First argument passed to .elementIdElements() should be a web element ID string. Received boolean.');\n      });\n    });\n\n    it('testElementActive', function () {\n      return Globals.protocolTest({\n        assertion({command}) {\n          assert.strictEqual(command, 'activeElement');\n        },\n        commandName: 'elementActive',\n        args: [function(result) {\n          assert.deepStrictEqual(result, {value: '12345-6789', status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdClear', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.strictEqual(command, 'clearElement');\n        },\n        commandName: 'elementIdClear',\n        args: ['TEST_ELEMENT', function(result) {\n          assert.deepStrictEqual(result, {value: null, status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdClear invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdClear',\n        args: [false]\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdClear\" command: First argument passed to .elementIdClear() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then((result) => {\n        assert.strictEqual(result, true);\n      });\n    });\n\n    it('testElementIdSelected', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.strictEqual(command, 'isElementSelected');\n          assert.ok(args.id instanceof WebElement);\n        },\n        commandName: 'elementIdSelected',\n        args: ['TEST_ELEMENT', function(result) {\n          assert.deepStrictEqual(result, {value: true, status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdSelected invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdSelected',\n        args: [false]\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdSelected\" command: First argument passed to .elementIdSelected() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdEnabled', function () {\n      return Globals.protocolTest({\n        assertion: function ({args, command}) {\n          assert.strictEqual(command, 'isElementEnabled');\n          assert.ok(args.id instanceof WebElement);\n        },\n        commandName: 'elementIdEnabled',\n        args: ['TEST_ELEMENT', function(result) {\n          assert.deepStrictEqual(result, {value: true, status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdEnabled invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdEnabled',\n        args: [false]\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdEnabled\" command: First argument passed to .elementIdEnabled() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdEquals', function () {\n      console.warn = function(value) {\n        assert.ok(value.includes('Please use WebElement.equals(a, b) instead from Selenium Webdriver.'));\n      };\n\n      return Globals.protocolTest({\n        assertion: function (opts) {\n          assert.strictEqual(opts.path, '/session/1352110219202/element/ELEMENT1/equals/ELEMENT2');\n        },\n        commandName: 'elementIdEquals',\n        args: ['ELEMENT1', 'ELEMENT2', function(res) {\n          assert.strictEqual(res.status, 0);\n        }]\n      });\n    });\n\n    it('testElementIdEquals invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdEquals',\n        args: [false, 'ELEMENT2']\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdEquals\" command: First argument passed to .elementIdEquals() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdAttribute', function () {\n      return Globals.protocolTest({\n        assertion({path}) {\n          assert.strictEqual(path, '/session/1352110219202/element/TEST_ELEMENT/attribute/test_attr');\n          // assert.strictEqual(args.name, 'test_attr');\n          // assert.ok(args.id instanceof WebElement);\n          // assert.strictEqual(command, 'getElementAttribute');\n        },\n        commandName: 'elementIdAttribute',\n        args: ['TEST_ELEMENT', 'test_attr', function(result) {\n          \n        }]\n      });\n    });\n\n    it('testElementIdAttribute invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdAttribute',\n        args: [false, 'test_attr']\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdAttribute\" command: First argument passed to .elementIdAttribute() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdClick', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.strictEqual(command, 'clickElement');\n        },\n        commandName: 'elementIdClick',\n        args: ['TEST_ELEMENT', function(result) {\n          assert.deepStrictEqual(result, {value: null, status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdClick invalid element ID', function () {\n      return Globals.protocolTest({\n        assertion: function (opts) {\n        },\n        commandName: 'elementIdClick',\n        args: [false]\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdClick\" command: First argument passed to .elementIdClick() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdCssProperty', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.strictEqual(args.propertyName, 'test_property');\n          assert.strictEqual(command, 'getElementValueOfCssProperty');\n        },\n        commandName: 'elementIdCssProperty',\n        args: ['TEST_ELEMENT', 'test_property', function(result) {\n          assert.deepStrictEqual(result, {value: '', status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdCssProperty invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdCssProperty',\n        args: [false, 'test_property']\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdCssProperty\" command: First argument passed to .elementIdCssProperty() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdProperty', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.strictEqual(args.name, 'test_property');\n          assert.strictEqual(command, 'getElementProperty');\n        },\n        commandName: 'elementIdProperty',\n        args: ['TEST_ELEMENT', 'test_property', function(result) {\n          assert.deepStrictEqual(result, {value: 'test_prop_value', status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdProperty invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdProperty',\n        args: [false, 'test_property']\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdProperty\" command: First argument passed to .elementIdProperty() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdDisplayed', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.ok(args.id instanceof WebElement);\n          assert.strictEqual(command, 'isElementDisplayed');\n        },\n        commandName: 'elementIdDisplayed',\n        args: ['TEST_ELEMENT', function(result) {\n          assert.deepStrictEqual(result, {value: true, status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdDisplayed invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdDisplayed',\n        args: [false]\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdDisplayed\" command: First argument passed to .elementIdDisplayed() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdLocation', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.ok(args.id instanceof WebElement);\n          assert.strictEqual(command, 'getElementRect');\n        },\n        commandName: 'elementIdLocation',\n        args: ['TEST_ELEMENT', function(result) {\n          assert.deepStrictEqual(result, {status: 0, value: {width: 100, height: 105, x: 10, y: 15}});\n        }]\n      });\n    });\n\n    it('testElementIdLocation invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdLocation',\n        args: [false]\n      })\n        .catch(err => {\n          assert.strictEqual(err.message, 'Error while running \"elementIdLocation\" command: First argument passed to .elementIdLocation() should be a web element ID string. Received boolean.');\n\n          return true;\n        }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdLocationInView', function () {\n      console.warn = function(text) {\n        assert.ok(text.includes('This command has been deprecated and is removed from the W3C Webdriver standard.'));\n      };\n\n      return Globals.protocolTest({\n        assertion: function (opts) {\n          assert.strictEqual(opts.path, '/session/1352110219202/element/TEST_ELEMENT/location_in_view');\n        },\n        commandName: 'elementIdLocationInView',\n        args: ['TEST_ELEMENT', function(result) {\n          assert.strictEqual(result.status, 0);\n        }]\n      });\n    });\n\n    it('testElementIdLocationInView invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdLocationInView',\n        args: [false]\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdLocationInView\" command: First argument passed to .elementIdLocationInView() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdName', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.ok(args.id instanceof WebElement);\n          assert.strictEqual(command, 'getElementTagName');\n        },\n        commandName: 'elementIdName',\n        args: ['TEST_ELEMENT', function(result) {\n          assert.deepStrictEqual(result, {value: 'div', status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdName invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdName',\n        args: [false]\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdName\" command: First argument passed to .elementIdName() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdSize', function () {\n      console.warn = function(value) {\n        assert.ok(value.includes('Please use .getElementRect().'));\n      };\n\n      return Globals.protocolTest({\n        assertion({command}) {\n          assert.strictEqual(command, 'getElementRect');\n        },\n        commandName: 'elementIdSize',\n        args: ['TEST_ELEMENT', function(result) {\n          assert.deepStrictEqual(result, {\n            status: 0,\n            value: {\n              height: 105,\n              width: 100,\n              x: 10,\n              y: 15\n            }\n          });\n        }]\n      });\n    });\n\n    it('testElementIdSize invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdSize',\n        args: [false]\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdSize\" command: First argument passed to .elementIdSize() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n\n    it('testElementIdText', function () {\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assert.strictEqual(command, 'getElementText');\n        },\n        commandName: 'elementIdText',\n        args: ['TEST_ELEMENT', function(result) {\n          assert.deepStrictEqual(result, {value: 'text', status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdText invalid element ID', function () {\n      return Globals.protocolTest({\n        commandName: 'elementIdText',\n        args: [false]\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdText\" command: First argument passed to .elementIdText() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n\n    });\n\n    it('testElementIdValueGet', function () {\n      console.warn = function(value) {\n        assert.ok(value.includes('This command has been deprecated and is removed from the W3C Webdriver standard. It is only working with legacy Selenium JSONWire protocol.'));\n      };\n\n      return Globals.protocolTest({\n        assertion({path}) {\n          assert.strictEqual(path, '/session/1352110219202/element/TEST_ELEMENT/attribute/value');\n        },\n        commandName: 'elementIdValue',\n        args: ['TEST_ELEMENT', function(result) {\n\n        }]\n      });\n    });\n\n    it('testElementIdValuePost', function () {\n      const assertions = [];\n\n      return Globals.protocolTest({\n        assertion({args, command}) {\n          assertions.push({args, command});\n        },\n        commandName: 'elementIdValue',\n        args: ['TEST_ELEMENT', 'test', function(result) {\n          // accounting for fallback for clearElement as well.\n          assert.strictEqual(assertions.length, 4);\n\n          assert.strictEqual(assertions[0].command, 'clearElement');\n          assert.ok(assertions[0].args.id instanceof WebElement);\n\n          // fallback for clearElement\n          assert.strictEqual(assertions[1].command, 'getElementProperty');\n          assert.strictEqual(assertions[2].command, 'sendKeysToElement');\n\n          assert.strictEqual(assertions[3].command, 'sendKeysToElement');\n          assert.strictEqual(assertions[3].args.text, 'test');\n          assert.deepStrictEqual(assertions[3].args.value, ['t', 'e', 's', 't']);\n          assert.ok(assertions[3].args.id instanceof WebElement);\n\n          assert.deepStrictEqual(result, {value: null, status: 0});\n        }]\n      });\n    });\n\n    it('testElementIdValuePost invalid element ID', function () {\n      return Globals.protocolTest({\n        assertion: function (opts) {\n        },\n        commandName: 'elementIdValue',\n        args: [false, 'test']\n      }).catch(err => {\n        assert.strictEqual(err.message, 'Error while running \"elementIdValue\" command: First argument passed to .elementIdValue() should be a web element ID string. Received boolean.');\n\n        return true;\n      }).then(result => assert.strictEqual(result, true));\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testEnsure.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('client.ensure', function () {\n  before(function () {\n    Globals.protocolBefore();\n  });\n\n  it('test ensure.titleIs', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting for title to be \"sample text\"');\n        assert.strictEqual(opts.result, true);\n      },\n      commandName: 'ensure.titleIs',\n      args: ['sample text']\n    });\n  });\n\n  it('test ensure.ableToSwitchToFrame', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting to be able to switch to frame');\n        assert.strictEqual(opts.result, true);\n      },\n      commandName: 'ensure.ableToSwitchToFrame'\n    });\n\n  });\n\n  it('test ensure.alertIsPresent', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting for alert to be present');\n      },\n      commandName: 'ensure.alertIsPresent'\n    });\n\n  });\n\n  it('test ensure.titleContains', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting for title to contain \"sample\"');\n        assert.strictEqual(opts.result, true);\n      },\n      commandName: 'ensure.titleContains',\n      args: ['sample']\n    });\n  });\n\n  it('test ensure.titleMatches', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting for title to match /sample/');\n        assert.strictEqual(opts.result, true);\n      },\n      commandName: 'ensure.titleMatches',\n      args: [/sample/]\n    });\n\n  });\n\n  it('test ensure.urlIs', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting for URL to be \"https://nightwatchjs.org\"');\n        assert.strictEqual(opts.result, true);\n      },\n      commandName: 'ensure.urlIs',\n      args: ['https://nightwatchjs.org']\n    });\n  });\n\n  it('test ensure.urlContains', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting for URL to contain \"nightwatchjs\"');\n        assert.strictEqual(opts.result, true);\n      },\n      commandName: 'ensure.urlContains',\n      args: ['nightwatchjs']\n    });\n  });\n\n  it('test ensure.urlMatches', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting for URL to match /nightwatchjs/');\n        assert.strictEqual(opts.result, true);\n      },\n      commandName: 'ensure.urlMatches',\n      args: [/nightwatchjs/]\n    });\n\n  });\n\n  it('test ensure.elementLocated', function (done) {\n    Globals.protocolTest({\n      async assertion(opts) {\n        try {\n          assert.strictEqual(opts.description, 'Waiting for element to be located By(css selector, element)');\n          const result = await opts.result.getId();\n          assert.strictEqual(result, '12345-6789');\n          done();\n        } catch (err) {\n          done(err);\n        }\n      },\n      commandName: 'ensure.elementLocated',\n      args: ['element']\n    });\n  });\n\n  it('test ensure.elementsLocated', function (done) {\n    Globals.protocolTest({\n      async assertion(opts) {\n        try {\n          assert.strictEqual(opts.description, 'Waiting for at least one element to be located By(css selector, element)');\n          assert.ok(Array.isArray(opts.result));\n          assert.strictEqual(opts.result.length, 1);\n          done();\n        } catch (err) {\n          done(err);\n        }\n      },\n      commandName: 'ensure.elementsLocated',\n      args: ['element']\n    });\n  });\n\n  it('test ensure.elementIsVisible', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting until element is visible');\n        assert.notStrictEqual(opts.result, null);\n      },\n      commandName: 'ensure.elementIsVisible',\n      args: ['@seleniumElement']\n    });\n  });\n\n  it('test ensure.elementIsEnabled', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting until element is enabled');\n        assert.notStrictEqual(opts.result, null);\n\n      },\n      commandName: 'ensure.elementIsEnabled',\n      args: ['@seleniumElement']\n    });\n  });\n\n  it('test ensure.elementIsSelected', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting until element is selected');\n        assert.notStrictEqual(opts.result, null);\n      },\n      commandName: 'ensure.elementIsSelected',\n      args: ['@seleniumElement']\n    });\n  });\n\n  it('test ensure.elementIsDisabled', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting until element is disabled');\n        assert.strictEqual(opts.result, null);\n      },\n      commandName: 'ensure.elementIsDisabled',\n      args: ['@seleniumElement']\n    });\n  });\n\n  it('test ensure.elementTextContains', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting until element text contains');\n        assert.notStrictEqual(opts.result, null);\n      },\n      commandName: 'ensure.elementTextContains',\n      args: ['@seleniumElement', 'text']\n    });\n  });\n\n\n  it('test ensure.elementTextIs', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting until element text is');\n        assert.notStrictEqual(opts.result, null);\n\n      },\n      commandName: 'ensure.elementTextIs',\n      args: ['@seleniumElement', 'text']\n    });\n  });\n\n  it('test ensure.elementTextMatches', function () {\n    return Globals.protocolTest({\n      assertion(opts) {\n        assert.strictEqual(opts.description, 'Waiting until element text matches');\n        assert.notStrictEqual(opts.result, null);\n\n      },\n      commandName: 'ensure.elementTextMatches',\n      args: ['@seleniumElement', /text/]\n    });\n  });\n\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testFirefox.js",
    "content": "const assert = require('assert');\n\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('Firefox API commands', function () {\n  before(function () {\n    Globals.protocolBefore();\n  });\n\n  it('getContext', function () {\n    return Globals.protocolTest({\n      assertion: function (opts) {\n        assert.strictEqual(opts.command, 'getContext');\n      },\n      commandName: 'firefox.getContext',\n      args: [],\n      browserDriver: 'firefox'\n    }).then((result) => {\n      assert.strictEqual(result.value, 'content');\n    });\n  });\n\n  it('setContext', function () {\n    return Globals.protocolTest({\n      assertion: function (opts) {\n        assert.strictEqual(opts.command, 'setContext');\n      },\n      commandName: 'firefox.setContext',\n      args: ['content'],\n      browserDriver: 'firefox'\n    }).then((result) => {\n      assert.strictEqual(result.value, null);\n    });\n  });\n\n  it('installAddon', function () {\n    return Globals.protocolTest({\n      assertion: function (opts) {\n        assert.strictEqual(opts.command, 'installAddon');\n      },\n      commandName: 'firefox.installAddon',\n      args: ['path/to/Addon'],\n      browserDriver: 'firefox'\n    }).then((result) => {\n      assert.strictEqual(result.value, '0c20aa29-db90-4eae-a3bb-012c6ae180b1');\n    });\n  });\n\n  it('uninstallAddon', function () {\n    return Globals.protocolTest({\n      assertion: function (opts) {\n        assert.strictEqual(opts.command, 'uninstallAddon');\n        assert.strictEqual(opts.id, '0c20aa29-db90-4eae-a3bb-012c6ae180b1');\n      },\n      commandName: 'firefox.uninstallAddon',\n      args: ['0c20aa29-db90-4eae-a3bb-012c6ae180b1'],\n      browserDriver: 'firefox'\n    }).then((result) => {\n      assert.strictEqual(result.value, null);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testFrame.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('client.frame', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testFrameDefault', function () {\n    return Globals.protocolTest({\n      assertion: function(frameId) {\n        assert.strictEqual(frameId, null);\n      },\n      commandName: 'frame', \n      args: []\n    });\n  });\n\n  it('testFramePost', function () {\n    return Globals.protocolTest({\n      assertion: function(frameId) {\n        assert.strictEqual(frameId, 0);\n      },\n      commandName: 'frame',\n      args: [0]\n    });\n  });\n\n  it('testFramePostWithZeroIndex', function () {\n    return Globals.protocolTest({\n      assertion: function(frameId) {\n        assert.strictEqual(frameId, 0);\n      },\n      commandName: 'frame',\n      args: [0]\n    });\n  });\n\n  it('testFramePostWithNull', function () {\n    return Globals.protocolTest({\n      assertion: function(frameId) {\n        assert.strictEqual(frameId, null);\n      },\n      commandName: 'frame',\n      args: [null]\n    });\n  });\n\n  it('testFramePostWithUndefined', function () {\n    return Globals.protocolTest({\n      assertion: function(frameId) {\n        assert.strictEqual(frameId, null);\n      },\n      commandName: 'frame',\n      args: []\n    });\n  });\n\n  it('testFrameParent', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts, null);\n      },\n      commandName: 'frameParent',\n      args: []\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testFrameCommand.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../lib/globals/commands-w3c');\nconst commandMocks = require('../../../lib/command-mocks.js');\n\ndescribe('client.frame()', function() {\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done, {globals: {\n      waitForConditionTimeout: 50,\n      waitForConditionPollInterval: 100\n    }});\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .frame with selector', function(done) {\n    commandMocks.frame({});\n\n    this.client.api.frame('#weblogin', function(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(function(err) {\n      done(err);\n    });\n  });\n\n  it('test .frame with name selector', function(done) {\n    commandMocks.findElements({value: '*[name=\"login\"]', response: {\n      value: [{\n        'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n      }]\n    }});\n    commandMocks.frame();\n    this.client.api.frame('login', function(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(function(err) {\n      done(err);\n    });\n  });\n\n  it('test .frame with id selector', function(done) {\n    commandMocks.findElements({value: '*[id=\"login\"]', response: {\n      value: [{\n        'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n      }]\n    }});\n    commandMocks.frame();\n    this.client.api.frame('login', function(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(function(err) {\n      done(err);\n    });\n  });\n\n\n  it('test .frame with bad selector', function(done) {\n    commandMocks.findElements({value: 'badElement', response: {value: []}, times: 2});\n    commandMocks.findElements({value: '*[name=\"badElement\"]', response: {value: []}, times: 2});\n    commandMocks.findElements({value: '*[id=\"badElement\"]', response: {value: []}, times: 2});\n    this.client.api.frame('badElement', function(result) {\n      assert.strictEqual(result.status, 0);\n    });\n\n    this.client.start(function(err) {\n      if (err) {\n        try {\n          assert.ok(err instanceof Error);\n          assert.strictEqual(err.message, 'Error while running \"frame\" command: Unable to locate frame element badElement.');\n          done();\n        } catch (err) {\n          done(err);\n        }\n       \n      } else {\n        done(new Error('Should result into error'));\n      }\n    });\n  });\n});"
  },
  {
    "path": "test/src/api/protocol/testGeolocation.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('Geolocation commands', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testSetGeolocation with correct options', function() {\n    const coordinates = {latitude: 35.689487, longitude: 139.691706, altitude: 5};\n\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/location');\n        assert.deepStrictEqual(opts.data, {\n          location: {latitude: 35.689487, longitude: 139.691706, altitude: 5}\n        });\n      },\n      commandName: 'appium.setGeolocation',\n      args: [coordinates]\n    });\n  });\n\n  it('testSetGeolocation with incorrect options', function() {\n    const coordinates = {latitude: 35.689487};\n\n    return Globals.protocolTest({\n      commandName: 'appium.setGeolocation',\n      args: [coordinates]\n    }).catch(err => {\n      return err;\n    }).then((result) => {\n      assert.ok(result instanceof Error);\n      assert.strictEqual(result.message.includes('Please provide both latitude and longitude while using setGeolocation.'), true);\n    });\n  });\n\n  it('testSetGeolocation with no options', function() {\n    return Globals.protocolTest({\n      commandName: 'appium.setGeolocation',\n      args: []\n    }).catch(err => {\n      return err;\n    }).then((result) => {\n      assert.ok(result instanceof Error);\n      assert.strictEqual(result.message.includes('Please provide both latitude and longitude while using setGeolocation.'), true);\n    });\n  });\n\n  it('testGetGeolocation', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.path, '/session/1352110219202/location');\n      },\n      commandName: 'appium.getGeolocation',\n      args: []\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testKeyboardInteraction.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('Keyboard interaction commands', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('test hideKeyboard', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/hide_keyboard');\n        assert.deepStrictEqual(opts.data, {});\n      },\n      commandName: 'appium.hideKeyboard',\n      args: []\n    });\n  });\n\n  it('test isKeyboardShown', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/is_keyboard_shown');\n      },\n      commandName: 'appium.isKeyboardShown',\n      args: []\n    });\n  });\n\n  it('test pressKeyCode - with just keycode', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/press_keycode');\n        assert.deepStrictEqual(opts.data, {\n          keycode: 15\n        });\n      },\n      commandName: 'appium.pressKeyCode',\n      args: [15]\n    });\n  });\n\n  it('test pressKeyCode - with all options', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/press_keycode');\n        assert.deepStrictEqual(opts.data, {\n          keycode: 15,\n          metastate: 14,\n          flags: 13\n        });\n      },\n      commandName: 'appium.pressKeyCode',\n      args: [15, 14, 13]\n    });\n  });\n\n  it('test pressKeyCode - with callback as second arg and then random args', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/press_keycode');\n        assert.deepStrictEqual(opts.data, {\n          keycode: 15\n        });\n      },\n      commandName: 'appium.pressKeyCode',\n      args: [15, () => {}, 14]\n    });\n  });\n\n  it('test pressKeyCode - with no options', function() {\n    return Globals.protocolTest({\n      commandName: 'appium.pressKeyCode',\n      args: []\n    }).catch(err => {\n      return err;\n    }).then((result) => {\n      assert.ok(result instanceof Error);\n      assert.strictEqual(result.message.includes('The first argument to pressKeyCode is mandatory and must be a number.'), true);\n    });\n  });\n\n  it('test longPressKeyCode - with just keycode', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/long_press_keycode');\n        assert.deepStrictEqual(opts.data, {\n          keycode: 15\n        });\n      },\n      commandName: 'appium.longPressKeyCode',\n      args: [15]\n    });\n  });\n\n  it('test longPressKeyCode - with 2 options', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/long_press_keycode');\n        assert.deepStrictEqual(opts.data, {\n          keycode: 15,\n          metastate: 14\n        });\n      },\n      commandName: 'appium.longPressKeyCode',\n      args: [15, 14]\n    });\n  });\n\n  it('test longPressKeyCode - with callback as second arg and then random args', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/device/long_press_keycode');\n        assert.deepStrictEqual(opts.data, {\n          keycode: 15\n        });\n      },\n      commandName: 'appium.longPressKeyCode',\n      args: [15, () => {}, 14]\n    });\n  });\n\n  it('test longPressKeyCode - with no options', function() {\n    return Globals.protocolTest({\n      commandName: 'appium.longPressKeyCode',\n      args: []\n    }).catch(err => {\n      return err;\n    }).then((result) => {\n      assert.ok(result instanceof Error);\n      assert.strictEqual(result.message.includes('The first argument to longPressKeyCode is mandatory and must be a number.'), true);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testKeys.js",
    "content": "const assert = require('assert');\nconst MockServer  = require('../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../lib/globals/commands.js');\n\ndescribe('client.keys()', function() {\n  let callbackResult;\n\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .keys() single', function() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/keys',\n      method: 'POST',\n      postdata: {value: ['\\uE007']},\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        value: null,\n        status: 0\n      })\n    });\n\n    this.client.api.keys('\\uE007', function callback(result) {\n      callbackResult = result;\n    });\n\n    return this.client.start(function() {\n      assert.ok(callbackResult, 'Result from callback is undefined');\n      assert.strictEqual(callbackResult.status, 0);\n      assert.strictEqual(callbackResult.value, null);\n    });\n  });\n\n  it('test .keys() array', function() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/keys',\n      method: 'POST',\n      postdata: {value: ['A', 'B']},\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        value: null,\n        status: 0\n      })\n    });\n\n    this.client.api.keys(['A', 'B'], function callback(result) {\n      callbackResult = result;\n    });\n\n    return this.client.start(function() {\n      assert.ok(callbackResult, 'Result from callback is undefined');\n      assert.strictEqual(callbackResult.status, 0);\n      assert.strictEqual(callbackResult.value, null);\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/api/protocol/testLog.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('session log commands', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testLog', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'sessionLog');\n      },\n      commandName: 'sessionLog',\n      args: []\n    }).then((result) => {\n      assert.deepStrictEqual(Object.keys(result[0]), ['level', 'type', 'timestamp', 'message']);\n    });\n  });\n\n  it('testLogTypes', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'sessionLogTypes');\n      },\n      commandName: 'sessionLogTypes',\n      args: []\n    }).then((result) => {\n      assert.deepStrictEqual(result, ['browser', 'driver']);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testMouseButtonClick.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('client.mouseButtonClick', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('test mouseButtonClick click left', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/click');\n        assert.deepStrictEqual(opts.data, {button: 0});\n      },\n      commandName: 'mouseButtonClick',\n      args: ['left']\n    });\n  });\n\n  it('test mouseButtonClick click right', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.deepStrictEqual(opts.data, {button: 2});\n      },\n      commandName: 'mouseButtonClick',\n      args: ['right']\n    });\n  });\n\n  it('test mouseButtonClick click middle', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.deepStrictEqual(opts.data, {button: 1});\n      },\n      commandName: 'mouseButtonClick',\n      args: ['middle']\n    });\n  });\n\n  it('test mouseButtonClick with callback only', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.deepStrictEqual(opts.data, {button: 0});\n      },\n      commandName: 'mouseButtonClick',\n      args: [function() {}]\n    });\n  });\n\n  it('test mouseButtonClick with no args', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.deepStrictEqual(opts.data, {button: 0});\n      },\n      commandName: 'mouseButtonClick',\n      args: []\n    });\n  });\n\n  it('test mouseButtonDown click left', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/buttondown');\n        assert.deepStrictEqual(opts.data, {button: 0});\n      },\n      commandName: 'mouseButtonDown',\n      args: ['left']\n    });\n  });\n\n  it('test mouseButtonDown click middle', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.deepStrictEqual(opts.data, {button: 1});\n      },\n      commandName: 'mouseButtonDown',\n      args: ['middle']\n    });\n  });\n\n  it('test mouseButtonDown with callback only', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.deepStrictEqual(opts.data, {button: 0});\n      },\n      commandName: 'mouseButtonDown',\n      args: [function() {\n\n      }]\n    });\n  });\n\n  it('test mouseButtonUp click right', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session/1352110219202/buttonup');\n        assert.deepStrictEqual(opts.data, {button: 2});\n      },\n      commandName: 'mouseButtonUp',\n      args: ['right']\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testMoveTo.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('browser commands', function() {\n  let args;\n  before(function() {\n    Globals.protocolBefore.call(this);\n    \n  });\n\n  beforeEach(function() {\n    this.client.transport.Actions.session.moveTo = function(opts) {\n      args = opts.args;\n\n      return Promise.resolve(null);\n    };\n  });\n\n  afterEach(function() {\n    args = null;\n  });\n\n  it('testMoveTo', function () {\n\n    return Globals.runProtocolTest({\n      assertion: function() {},\n      commandName: 'moveTo',\n      args: ['testElement', 0, 1]\n    }, this.client).then(_ => {\n      assert.deepStrictEqual(args, ['testElement', 0, 1]);\n    });\n  });\n\n  it('testMoveTo - no webElementId', function() {\n\n    return Globals.runProtocolTest({\n      assertion: function() {},\n      commandName: 'moveTo',\n      args: [2, 1]\n    }, this.client).then(_ => {\n      assert.deepStrictEqual(args, ['pointer', 2, 1]);\n    });\n  });\n\n  it('testMoveTo - null webElementId', function() {\n    return Globals.runProtocolTest({\n      assertion: function() {},\n      commandName: 'moveTo',\n      args: [null, 2, 1]\n    }, this.client).then(_ => {\n      assert.deepStrictEqual(args, ['pointer', 2, 1]);\n    });\n  });\n\n  it('testMove - elementId only parameters', function() {\n    Globals.runProtocolTest({\n      assertion: function() {},\n      commandName: 'moveTo',\n      args: ['testElement']\n    }, this.client).then(_ => {\n      assert.deepStrictEqual(args, ['testElement', 0, 0]);\n    });\n  });\n\n  it('testMove - elementId only parameters', function() {\n    Globals.runProtocolTest({\n      assertion: function() {},\n      commandName: 'moveTo',\n      args: []\n    }, this.client).then(_ => {\n      assert.deepStrictEqual(args, ['pointer', 0, 0]);\n    });\n  });\n    \n  it('testMove - invalid parameters', function(done) {\n    Globals.runProtocolTest({\n      assertion: function() {},\n      commandName: 'moveTo',\n      args: [NaN]\n    }, this.client)\n      .then(_ => done(new Error('should result into error')))\n      .catch(err => done());\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testOrientation.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\nconst {strictEqual} = assert;\n\ndescribe('orientation commands', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testGetOrientation', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        strictEqual(opts.method, 'GET');\n        strictEqual(opts.path, '/session/1352110219202/orientation');\n      },\n      commandName: 'getOrientation',\n      args: []\n    });\n  });\n\n  it('testSetOrientation', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        strictEqual(opts.method, 'POST');\n        strictEqual(opts.path, '/session/1352110219202/orientation');\n        assert.deepStrictEqual(opts.data, {orientation: 'LANDSCAPE'});\n      },\n      commandName: 'setOrientation',\n      args: ['LANDSCAPE']\n    });\n  });\n\n  it('testSetOrientationInvalid', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n\n      },\n      commandName: 'setOrientation',\n      args: ['TEST']\n    }).catch(err => {\n      strictEqual(err.message, 'Error while running \"setOrientation\" command: Invalid screen orientation value specified. Accepted values are: LANDSCAPE, PORTRAIT');\n\n      return true;\n    }).then(result => assert.strictEqual(result, true));\n  });\n\n  it('testGetOrientation - appium', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        strictEqual(opts.method, 'GET');\n        strictEqual(opts.path, '/session/1352110219202/orientation');\n      },\n      commandName: 'appium.getOrientation',\n      args: []\n    });\n  });\n\n  it('testSetOrientation - appium', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        strictEqual(opts.method, 'POST');\n        strictEqual(opts.path, '/session/1352110219202/orientation');\n        assert.deepStrictEqual(opts.data, {orientation: 'LANDSCAPE'});\n      },\n      commandName: 'appium.setOrientation',\n      args: ['LANDSCAPE']\n    });\n  });\n\n  it('testSetOrientationInvalid - appium', function () {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n\n      },\n      commandName: 'appium.setOrientation',\n      args: ['TEST']\n    }).catch(err => {\n      strictEqual(err.message, 'Error while running \"appium.setOrientation\" command: Invalid screen orientation value specified. Accepted values are: LANDSCAPE, PORTRAIT');\n\n      return true;\n    }).then(result => assert.strictEqual(result, true));\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testReleaseMouseButton.js",
    "content": "const assert = require('assert');\nconst CommandGlobals = require('../../../lib/globals/commands-w3c.js');\n\ndescribe('client.release()', function() {\n  let callbackResult;\n\n  before(function(done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test .release() - successful', function() {\n\n    this.client.transport.driver.actions = function() {\n      return {\n        release: function() {\n          return {\n            perform: function() {\n              return Promise.resolve();\n            }\n          };\n        }\n      };\n    };\n\n    this.client.api.releaseMouseButton(function callback(result) {\n      callbackResult = result;\n    });\n\n    return this.client.start(function() {\n      assert.ok(callbackResult, 'Result from callback is undefined');\n      assert.strictEqual(callbackResult.status, 0);\n      assert.strictEqual(callbackResult.value, null);\n    });\n  });\n\n  it('test .release - failed', function() {\n\n    this.client.transport.driver.actions = function() {\n      return {\n        release: function() {\n          return {\n            perform: function() {\n              return Promise.reject(new Error('no such window'));\n            }\n          };\n        }\n      };\n    };\n\n    this.client.api.releaseMouseButton(function callback(result) {\n      callbackResult = result;\n    });\n\n    return this.client.start(function() {\n      assert.ok(callbackResult, 'Result from callback is undefined');\n      assert.strictEqual(callbackResult.status, -1);\n      assert.strictEqual(callbackResult.error.message, 'no such window');\n    });\n  });\n});"
  },
  {
    "path": "test/src/api/protocol/testResetApp.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('App reset command', function () {\n  before(function () {\n    Globals.protocolBefore();\n  });\n\n  it('testResetApp', function () {\n    return Globals.protocolTest({\n      assertion: function (opts) {\n        assert.strictEqual(opts.path, '/session/1352110219202/appium/app/reset');\n      },\n      commandName: 'appium.resetApp',\n      args: []\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testScreenshot.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('client.screenshot', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testScreenshot', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'screenshot');\n      },\n      commandName: 'screenshot',\n      args: []\n    }).then((result) => {\n      assert.strictEqual(result, 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==');\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testSendKeys.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('sendKeys command', function () {\n  before(function () {\n    Globals.protocolBefore();\n  });\n\n  it('test sendKeys', function () {\n    const commands = [];\n\n    return Globals.protocolTest({\n      commandName: 'sendKeys',\n      args: [\n        'weblogin',\n        'nightwatch',\n        function (result) {\n          assert.deepStrictEqual(result.value, null);\n          assert.deepStrictEqual(result.status, 0);\n        }\n      ],\n      assertion: function (opts) {\n        commands.push(opts.command);\n      }\n    }).then(() => {\n      assert.deepStrictEqual(commands, ['findElements', 'sendKeysToElement']);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testSession.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('session commands', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testSessions', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'GET');\n        assert.strictEqual(opts.path, '/sessions');\n      },\n      commandName: 'sessions',\n      args: []\n    });\n  });\n\n  it('testSessionDefault', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'GET');\n        assert.strictEqual(opts.path, '/session/1352110219202');\n      },\n      commandName: 'session',\n      args: []\n    });\n  });\n\n  it('testSessionGETImplicit', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'GET');\n        assert.strictEqual(opts.path, '/session/1352110219202');\n      },\n      commandName: 'session',\n      args: []\n    });\n  });\n\n  it('testSessionGETExplicit', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'GET');\n        assert.strictEqual(opts.path, '/session/1352110219202');\n      },\n      commandName: 'session',\n      args: ['GET']\n    });\n  });\n\n  it('testSessionGETImplicitById', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'GET');\n        assert.strictEqual(opts.path, '/session/1352110219202');\n      },\n      commandName: 'session',\n      args: ['1352110219202']\n    });\n  });\n\n  it('testSessionGETExplicitById', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'GET');\n        assert.strictEqual(opts.path, '/session/1352110219202');\n      },\n      commandName: 'session',\n      args: ['GET', '1352110219202']\n    });\n  });\n\n  it('testSessionDELETE', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'DELETE');\n        assert.strictEqual(opts.path, '/session/1352110219202');\n      },\n      commandName: 'session',\n      args: ['DELETE']\n    });\n  });\n\n  it('testSessionDELETEWithCallback', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'DELETE');\n        assert.strictEqual(opts.path, '/session/1352110219202');\n      },\n      commandName: 'session',\n      args: ['DELETE', function() {\n\n      }]\n    });\n  });\n\n  it('testSessionDELETEById', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'DELETE');\n        assert.strictEqual(opts.path, '/session/1352110219202');\n      },\n      commandName: 'session',\n      args: ['DELETE', '1352110219202']\n    });\n  });\n\n  it('testSessionPOST', function() {\n    Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'POST');\n        assert.strictEqual(opts.path, '/session');\n      },\n      commandName: 'session',\n      args: ['POST']\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testSetValue.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('setValue command', function () {\n  before(function () {\n    Globals.protocolBefore();\n  });\n\n  it('should clear value and setValue', function () {\n    return Globals.protocolTest({\n      commandName: 'setValue',\n      args: [\n        'weblogin',\n        'nightwatch',\n        function (result) {\n          assert.deepStrictEqual(result.value, null);\n          assert.deepStrictEqual(result.status, 0);\n        }\n      ],\n      assertion: function (opts) {\n        assert.ok(['findElements', 'clearElement', 'sendKeysToElement'].includes(opts.command));\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testSource.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('client.source', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('client.source() get command', function() {\n    return Globals.protocolTest({\n      assertion: opts => {\n        assert.strictEqual(opts.command, 'getPageSource');\n      },\n      commandName: 'source',\n      args: []\n    }).then((result) => {\n      assert.strictEqual(result, '<html><body></body></html>');\n    });\n  });\n\n  it('client.source() get command callback', function(done) {\n    Globals.protocolTest({\n      commandName: 'source',\n      args: [\n        function (result) {\n          try {\n            assert.strictEqual(result.status, 0);\n            assert.ok(result.value.indexOf('<title>NightwatchJS</title>') > -1, 'Found <title> tag in response');\n            assert.ok(true, 'GET source callback called');\n            done();\n          } catch (err) {\n            done(err);\n          }\n        }\n      ],\n      mockDriverOverrides: {\n        getPageSource() {\n          return '<!DOCTYPE html><html><head><title>NightwatchJS</title></head><body><div id=\\'some_id\\'>some div content</div></body></html>';\n        }\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testStatus.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('client.status', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testStatus', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'GET');\n        assert.strictEqual(opts.path, '/status');\n      },\n      commandName: 'status',\n      args: []\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testSubmit.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('client.submit', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testSubmit', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'submit');\n      },\n      commandName: 'submit',\n      args: ['TEST_ELEMENT']\n    }).then((result) => {\n      assert.deepStrictEqual(result, null);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testTimeouts.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('timeouts commands', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testTimeoutsValid', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'timeouts');\n        assert.deepStrictEqual(opts.data, {'script': 1000});\n      },\n      commandName: 'timeouts',\n      args: ['script', 1000]\n    }).then((result) => {\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('testTimeouts invalid type', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n      },\n      commandName: 'timeouts',\n      args: ['nonscript', 1000]\n    }).catch(err => {\n      assert.strictEqual(err.message, 'Error while running \"timeouts\" command: Invalid timeouts type value: nonscript. Accepted values are: script, implicit, pageLoad');\n\n      return true;\n    }).then(result => assert.strictEqual(result, true));\n  });\n\n  it('testTimeouts invalid value', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n      },\n      commandName: 'timeouts',\n      args: ['script']\n    }).catch(err => {\n      assert.strictEqual(err.message, 'Error while running \"timeouts\" command: Second argument to .timeouts() command must be a number. undefined given.');\n\n      return true;\n    }).then(result => assert.strictEqual(result, true));\n  });\n\n  it('testTimeoutsAsyncScript', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'timeouts');\n        assert.deepStrictEqual(opts.data, {script: 1000});\n      },\n      commandName: 'timeoutsAsyncScript',\n      args: [1000]\n    }).then((result) => {\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('testTimeoutsImplicitWait', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'timeouts');\n        assert.deepStrictEqual(opts.data, {implicit: 1000});\n      },\n      commandName: 'timeoutsImplicitWait',\n      args: [1000]\n    }).then((result) => {\n      assert.strictEqual(result, null);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testTitle.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('client.title', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('testTitle', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'title');\n      },\n      commandName: 'title',\n      args: []\n    }).then((result) => {\n      assert.strictEqual(result, 'nightwatch');\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testUploadFile.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\nconst mockery = require('mockery');\n\ndescribe('uploadFile command', function () {\n  before(function () {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n    Globals.protocolBefore();\n  });\n\n  after(function() {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n  });\n\n  it('should call FileDetector Api from selenium', function () {\n    let fakeRemoteCalled = false;\n    class FakeRemote {}\n    FakeRemote.FileDetector = class {\n      constructor() {\n        fakeRemoteCalled = true;\n      }\n    };\n\n    mockery.registerMock('selenium-webdriver/remote', FakeRemote);\n    const commands = [];\n\n    return Globals.protocolTest({\n      commandName: 'uploadFile',\n      args: [\n        'css selector', '#weblogin', '/file.js',\n        function (result) {\n          assert.deepStrictEqual(result.value, null);\n          assert.deepStrictEqual(result.status, 0);\n        }\n      ],\n\n      assertion(opts) {\n        commands.push(opts.command);\n      }\n    }).then(() => {\n      assert.deepStrictEqual(commands, ['findElements', 'setFileDetector', 'sendKeysToElement']);\n      assert.strictEqual(fakeRemoteCalled, true);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testUrl.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('url', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('client.url() get', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'url');\n      },\n      commandName: 'url',\n      args: []\n    }).then((result) => {\n      assert.strictEqual(result, 'http://localhost');\n    });\n  });\n\n  it('client.url() new', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'url');\n        assert.strictEqual(opts.url, 'http://localhost');\n      },\n      commandName: 'url',\n      args: ['http://localhost']\n    }).then((result) => {\n      assert.strictEqual(result, null);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testWindowCommands.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('window commands', function() {\n  before(function(done) {\n    Globals.protocolBefore({}, done);\n  });\n\n  after(function(done) {\n    Globals.protocolAfter(done);\n  });\n\n  it('test .windowHandle()', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'windowHandle');\n      },\n      commandName: 'windowHandle',\n      args: []\n    }).then((result) => {\n      assert.strictEqual(result, 'CDwindow-BE13CA812F066254342F4FEB180D14ED');\n    });\n  });\n\n  it('test .windowHandles()', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'windowHandles');\n      },\n      commandName: 'windowHandles',\n      args: []\n    }).then((result) => {\n      assert.deepStrictEqual(result, ['CDwindow-BE13CA812F066254342F4FEB180D14ED']);\n    });\n  });\n\n  it('test .minimizeWindow()', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'minimizeWindow');\n      },\n      commandName: 'minimizeWindow'\n    }).then((result) => {\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('test .windowMaximize()', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'windowMaximize');\n      },\n      commandName: 'windowMaximize',\n      args: []\n    }).then((result) => {\n      assert.strictEqual(result, null);\n    });\n  });\n\n  it('test .openNewWindow()', function() {\n    return Globals.protocolTestWebdriver({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'openNewWindow');\n      },\n      commandName: 'openNewWindow',\n      args: []\n    }).then((result) => {\n      assert.strictEqual(result, null);\n    });\n  });\n\n\n  it('test .openNewWindow() with callback', function() {\n    return Globals.protocolTestWebdriver({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'openNewWindow');\n        assert.strictEqual(opts.type, 'tab');\n      },\n      commandName: 'openNewWindow',\n      args: [function(result) {\n        assert.deepStrictEqual(result, {\n          value: null,\n          status: 0\n        });\n      }]\n    });\n  });\n\n  it('test .openNewWindow() W3C WebDriver with specified type=window', function() {\n    return Globals.protocolTestWebdriver({\n      assertion: function(opts) {\n        assert.strictEqual(opts.command, 'openNewWindow');\n        assert.strictEqual(opts.type, 'window');\n      },\n      commandName: 'openNewWindow',\n      args: ['window']\n    }).then((result) => {\n      assert.strictEqual(result, null);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testWindowPosition.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('windowPosition', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('test .windowPosition() without offsets and callback', function(done) {\n    Globals.protocolTest({\n      assertion: function(opts) {\n        assert.strictEqual(opts.method, 'GET');\n        assert.strictEqual(opts.path, '/session/1352110219202/window/current/position');\n      },\n      commandName: 'windowPosition',\n      args: ['current']\n    }).catch(err => {\n      assert.strictEqual(err.message, 'Error while running \"windowPosition\" command: Second argument passed to .windowPosition() should be a callback when not passing offsetX and offsetY - undefined given.');\n      done();\n    }).catch(err => done(err));\n  });\n\n  it('test .windowPosition() validation errors', async function() {\n    let msgone;\n    let msgtwo;\n    let msgthree;\n\n    // try {\n    //   await Globals.protocolTest({\n    //     commandName: 'windowPosition',\n    //     args: [function () {}]\n    //   });\n    // } catch (err) {\n    //   msgone = err.message;\n    // }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowPosition',\n        args: ['current', 'a', 10]\n      });\n    } catch (err) {\n      msgtwo = err.message;\n    }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowPosition',\n        args: ['current', 10, 'a']\n      });\n    } catch (err) {\n      msgthree = err.message;\n    }\n\n    //assert.strictEqual(msgone, 'Error while running \"windowPosition\" command: First argument must be a window handle string.');\n    assert.strictEqual(msgtwo, 'Error while running \"windowPosition\" command: offsetX argument passed to .windowPosition() must be a number.');\n    assert.strictEqual(msgthree, 'Error while running \"windowPosition\" command: offsetY argument passed to .windowPosition() must be a number.');\n\n  });\n\n  it('test .windowPosition() GET', function() {\n    return Globals.protocolTest({\n      commandName: 'windowPosition',\n      args: ['current', function(result) {\n        if (result instanceof Error) {\n          throw result;\n        }\n\n        assert.deepStrictEqual(result, {status: 0, value: {x: 10, y: 10}});\n      }]\n    });\n  });\n\n  it('test .windowPosition() POST', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.deepStrictEqual(opts.args[0], {x: 10, y: 10});\n      },\n      commandName: 'windowPosition',\n      args: ['current', 10, 10]\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/api/protocol/testWindowRect.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('windowRect', function() {\n  before(function() {\n    Globals.protocolBefore();\n  });\n\n  it('test .windowRect() validation errors', async function() {\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowRect',\n        args: [{width: 'a', height: 10}]\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowRect\" command: Width argument passed to .windowRect() must be a number; received: string (a).');\n    }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowRect',\n        args: [{width: 10, height: 'a'}]\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowRect\" command: Height argument passed to .windowRect() must be a number; received: string (a).');\n    }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowRect',\n        args: [{width: 10}]\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowRect\" command: Attributes \"width\" and \"height\" must be specified together.');\n    }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowRect',\n        args: [{x: 'a', y: 10}]\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowRect\" command: X position argument passed to .windowRect() must be a number; received: string (a).');\n    }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowRect',\n        args: [{x: 10, y: 'a'}]\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowRect\" command: Y position argument passed to .windowRect() must be a number; received: string (a).');\n    }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowRect',\n        args: [{x: 10}]\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowRect\" command: Attributes \"x\" and \"y\" must be specified together.');\n    }\n  });\n\n  it('test .windowRect() GET', function() {\n    return Globals.protocolTest({\n      commandName: 'windowRect',\n      args: [null, function(result) {\n        if (result instanceof Error) {\n          throw result;\n        }\n\n        assert.deepStrictEqual(result, {status: 0, value: {width: 100, height: 100, x: 10, y: 10}});\n      }]\n    });\n  });\n\n  it('test .windowRect() POST', function() {\n    return Globals.protocolTest({\n      assertion: function(opts) {\n        assert.deepStrictEqual(opts.args[0], {width: 10, height: 10, x: 10, y: 10});\n      },\n      commandName: 'windowRect',\n      args: [{width: 10, height: 10, x: 10, y: 10}]\n    }).then(result => {\n      assert.strictEqual(result, null);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/api/protocol/testWindowSize.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../../lib/globals.js');\n\ndescribe('windowSize', function () {\n  before(function () {\n    Globals.protocolBefore();\n  });\n\n  it('test .windowSize() errors', async function () {\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowSize',\n        args: [function () {\n        }]\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowSize\" command: First argument must be a window handle string.');\n    }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowSize',\n        args: [function () {\n        }]\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowSize\" command: First argument must be a window handle string.');\n    }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowSize',\n        args: ['current', 'a', 10]\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowSize\" command: Width argument passed to .windowSize() must be a number.');\n    }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowSize',\n        args: ['current', 10, 'a']\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowSize\" command: Height argument passed to .windowSize() must be a number.');\n    }\n\n    try {\n      await Globals.protocolTest({\n        commandName: 'windowSize',\n        args: ['current', 10]\n      });\n\n      throw new Error('Unexpected error');\n    } catch (err) {\n      assert.strictEqual(err.message, 'Error while running \"windowSize\" command: Second argument passed to .windowSize() should be a callback when not passing width and height - number given.');\n    }\n  });\n\n  it('test .windowSize() GET', function () {\n    return Globals.protocolTest({\n      commandName: 'windowSize',\n      args: ['current', function (result) {\n        if (result instanceof Error) {\n          throw result;\n        }\n\n        assert.deepStrictEqual(result, {status: 0, value: {width: 100, height: 100, x: 10, y: 10}});\n      }]\n    });\n  });\n\n  it('test .windowSize() POST', function () {\n    return Globals.protocolTest({\n      assertion: function (opts) {\n        assert.deepStrictEqual(opts.args[0], {width: 10, height: 10});\n      },\n      commandName: 'windowSize',\n      args: ['current', 10, 10]\n    });\n  });\n\n  it('test .windowSize() with W3C Webdriver API - GET', function () {\n    return Globals.protocolTestWebdriver({\n      commandName: 'windowSize',\n      args: ['current', function (result) {\n        if (result instanceof Error) {\n          throw result;\n        }\n\n        assert.deepStrictEqual(result, {status: 0, value: {width: 100, height: 100, x: 10, y: 10}});\n      }]\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/actions-api/asyncPerformActionsTest.js",
    "content": "const path = require('path');\nconst nock = require('nock');\nconst assert = require('assert');\nconst common = require('../../../common.js');\nconst nocks = require('../../../lib/nocks.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('actions api tests - async perform', function() {\n\n  before(function () {\n    nocks.cleanAll();\n    try {\n      nocks.enable();\n    } catch (e) {\n    }\n\n  });\n  after(function(){\n    nocks.disable();\n  });\n\n  it('run basic test with actions and async perform callback', function() {\n    let actionsPerformed = false;\n    const testsPath = path.join(__dirname, '../../../apidemos/actions-api/asyncActionsApi.js');\n\n    nocks\n      .createW3cSession()\n      .urlW3c()\n      .elementFoundW3c()\n      .deleteW3cSession();\n\n\n    nock('http://localhost:10195')\n      .post('/session/13521-10219-202/actions')\n      .reply(200, function() {\n        actionsPerformed = true;\n\n        return {\n          value: null\n        };\n      });\n\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n        assert.strictEqual(actionsPerformed, true);\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      selenium_host: null,\n      output: false,\n      globals\n    }));\n  });\n\n});\n"
  },
  {
    "path": "test/src/apidemos/actions-api/performActionsTest.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('actions api tests', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('run basic test with actions', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/actions-api/actionsApi.js');\n\n    Mocks.createNewW3CSession({\n      testName: 'Actions API demo tests'\n    });\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/url',\n      statusCode: 200,\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/actions',\n      method: 'POST',\n      response: JSON.stringify({\n        value: null\n      })\n    });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      selenium_host: null,\n      output: false,\n      globals\n    }));\n  });\n\n});\n"
  },
  {
    "path": "test/src/apidemos/angular-test/runAngularDemo.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('angular demo tests', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('run test with global element()', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/angular-test/angularTodoListWithElementGlobal.js');\n    setupMocks({testSuiteName: 'angularjs homepage todo list - with element global'});\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium_host: null,\n      output: false,\n      globals\n    }));\n  });\n\n  it('run test with global element() - async', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/angular-test/angularTodoListWithElementGlobalAsync.js');\n    setupMocks({testSuiteName: 'angularjs homepage todo list - with element global async'});\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 100,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium_host: null,\n      output: false,\n      globals\n    }));\n  });\n\n  it('run test with classic apis', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/angular-test/angularTodoListWithClassicApis.js');\n    setupMocks({testSuiteName: 'angularjs homepage todo list - with classic apis'});\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium_host: null,\n      output: false,\n      globals\n    }));\n  });\n\n  it('run test with global element() and stale element error', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/angular-test/angularTodoListWithElementGlobalAndError.js');\n    Mocks\n      .createNewW3CSession({\n        postdata: {\n          capabilities: {firstMatch: [{}], alwaysMatch: {browserName: 'chrome', 'goog:chromeOptions': {}}}\n        }\n      })\n      .findElements({\n        value: '[ng-model=\"todoList.todoText\"]', response: {\n          value: [\n            {\n              'element-6066-11e4-a52e-4f735466cecf': '1666be97-5c43-4064-b145-bd5676a9a361'\n            }\n          ]\n        }\n      })\n      .findElements({\n        value: '[ng-model=\"todoList.todoText\"]', response: {\n          value: [\n            {\n              'element-6066-11e4-a52e-4f735466cecf': '1666be97-5c43-4064-b145-bd5676a9a361'\n            }\n          ]\n        }\n      })\n      .setElementValue({\n        elementId: '1666be97-5c43-4064-b145-bd5676a9a361',\n        text: 'what is nightwatch?'\n      })\n      .setElementValue({\n        elementId: '1666be97-5c43-4064-b145-bd5676a9a361',\n        text: 'what is nightwatch?',\n        response: {\n          value: {\n            error: 'stale element reference',\n            message: 'stale element reference: element is not attached to the page document\\n' +\n              '  (Session info: headless chrome=95.0.4638.69)',\n            stacktrace: ''\n          }\n        },\n        statusCode: 404\n      })\n      .setElementValue({\n        elementId: '1666be97-5c43-4064-b145-bd5676a9a361',\n        text: 'what is nightwatch?'\n      });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium_host: null,\n      output: false,\n      globals\n    }));\n  });\n\n  it('run test with global element() and stale element error and retry success', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/angular-test/angularTodoListWithElementGlobalAndError.js');\n    Mocks\n      .createNewW3CSession({\n        postdata: {\n          capabilities: {firstMatch: [{}], alwaysMatch: {browserName: 'chrome', 'goog:chromeOptions': {}}}\n        }\n      })\n      .findElements({\n        value: '[ng-model=\"todoList.todoText\"]', response: {\n          value: [\n            {\n              'element-6066-11e4-a52e-4f735466cecf': '1666be97-5c43-4064-b145-bd5676a9a361'\n            }\n          ]\n        }\n      })\n      .setElementValue({\n        elementId: '1666be97-5c43-4064-b145-bd5676a9a361',\n        text: 'what is nightwatch?'\n      })\n      .setElementValue({\n        elementId: '1666be97-5c43-4064-b145-bd5676a9a361',\n        text: 'what is nightwatch?',\n        response: {\n          value: {\n            error: 'stale element reference',\n            message: 'stale element reference: element is not attached to the page document\\n' +\n              '  (Session info: headless chrome=95.0.4638.69)',\n            stacktrace: ''\n          }\n        },\n        statusCode: 404\n      })\n      .findElements({\n        value: '[ng-model=\"todoList.todoText\"]', response: {\n          value: [\n            {\n              'element-6066-11e4-a52e-4f735466cecf': '1666be97-5c43-4064-b145-bd5676a9a360'\n            }\n          ]\n        }\n      })\n      .setElementValue({\n        elementId: '1666be97-5c43-4064-b145-bd5676a9a360',\n        text: 'what is nightwatch?'\n      });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium_host: null,\n      output: false,\n      globals\n    }));\n  });\n});\n\nconst setupMocks = function({testSuiteName} = {}) {\n  Mocks\n    .createNewW3CSession({\n      postdata: {\n        capabilities: {firstMatch: [{}], alwaysMatch: {browserName: 'chrome', 'goog:chromeOptions': {}}}\n      }\n    })\n    .navigateTo({url: 'http://localhost'})\n    .navigateTo({url: 'https://angularjs.org'})\n    .findElements({\n      value: '[ng-model=\"todoList.todoText\"]', response: {\n        value: [\n          {\n            'element-6066-11e4-a52e-4f735466cecf': '1666be97-5c43-4064-b145-bd5676a9a361'\n          }\n        ]\n      }\n    })\n    .setElementValue({\n      elementId: '1666be97-5c43-4064-b145-bd5676a9a361',\n      text: 'what is nightwatch?'\n    })\n    .findElements({\n      value: '[value=\"add\"]', response: {\n        value: [\n          {\n            'element-6066-11e4-a52e-4f735466cecf': '7ef31e53-de68-4420-903e-465e6a3ff351'\n          }\n        ]\n      }\n    })\n    .clickElement({\n      elementId: '7ef31e53-de68-4420-903e-465e6a3ff351'\n    })\n    .findElements({\n      times: 2, value: '[ng-repeat=\"todo in todoList.todos\"]', response: {\n        value: [\n          {\n            'element-6066-11e4-a52e-4f735466cecf': 'a1c2de89-42c2-4f6c-84fa-f6a656034838'\n          },\n          {\n            'element-6066-11e4-a52e-4f735466cecf': 'aac4752d-6245-4a79-921a-127ee752eca0'\n          },\n          {\n            'element-6066-11e4-a52e-4f735466cecf': '0cf4c839-a829-4a64-a01b-30047fd44397'\n          }\n        ]\n      }\n    })\n    .getElementText({\n      elementId: '0cf4c839-a829-4a64-a01b-30047fd44397',\n      responseText: 'what is nightwatch?'\n    })\n    .findElementFromParent({\n      elementId: '0cf4c839-a829-4a64-a01b-30047fd44397',\n      response: {\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '3ee091d4-0cce-4481-aabb-f5bef32a7bd9'\n        }\n      }\n    })\n    .findElements({\n      times: 2, value: '[ng-repeat=\"todo in todoList.todos\"] input', response: {\n        value: [\n          {\n            'element-6066-11e4-a52e-4f735466cecf': '3ee091d4-0cce-4481-aabb-f5bef32a7bd1'\n          },\n          {\n            'element-6066-11e4-a52e-4f735466cecf': '3ee091d4-0cce-4481-aabb-f5bef32a7bd9'\n          },\n          {\n            'element-6066-11e4-a52e-4f735466cecf': '3ee091d4-0cce-4481-aabb-f5bef32a7bd0'\n          }\n        ]\n      }\n    })\n    .clickElement({\n      elementId: '3ee091d4-0cce-4481-aabb-f5bef32a7bd9'\n    })\n    .clickElement({\n      elementId: '3ee091d4-0cce-4481-aabb-f5bef32a7bd0'\n    })\n    .findElements({\n      value: '*[module=todoApp] li .done-true', response: {\n        value: [\n          {\n            'element-6066-11e4-a52e-4f735466cecf': '6b23e23b-b083-4c58-ac63-90d44c47e9ae'\n          },\n          {\n            'element-6066-11e4-a52e-4f735466cecf': 'aeb0ace1-296a-4258-9aab-38e6a3160288'\n          }\n        ]\n      }\n    });\n};\n"
  },
  {
    "path": "test/src/apidemos/appium/testAppiumAPI.js",
    "content": "const {strictEqual} = require('assert');\nconst path = require('path');\nconst common = require('../../../common.js');\nconst MockServer = require('../../../lib/mockserver.js');\nconst NightwatchClient = common.require('index.js');\n\ndescribe('appium api demos', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init(undefined, {port: 4723});\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    this.server.close(function () {\n      done();\n    });\n  });\n\n  it.skip('run appium api demo tests basic', function () {\n    const testsPath = path.join(__dirname, '../../../apidemos/appium/appiumTest.js');\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    MockServer\n      .addMock({\n        url: '/wd/hub/session',\n        method: 'POST',\n        response: JSON.stringify({\n          value: {\n            sessionId: '13521-10219-202',\n            version: 'TEST',\n            platform: 'TEST'\n          }\n        })\n      }, true)\n      .addMock({\n        url: '/wd/hub/session/13521-10219-202/elements',\n        postdata: {\n          using: 'accessibility id',\n          value: 'Search Wikipedia'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '0'}]\n        })\n      }, true, true)\n      .addMock({\n        url: '/wd/hub/session/13521-10219-202/element',\n        postdata: {\n          using: 'class name',\n          value: 'android.widget.ImageButton'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: {'element-6066-11e4-a52e-4f735466cecf': '1'}\n        })\n      }, true)\n      .addMock({\n        url: '/wd/hub/session/13521-10219-202/elements',\n        postdata: {\n          using: 'id',\n          value: 'com.app:id/search'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          status: 0,\n          state: 'success',\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '2'}]\n        })\n      }, true)\n      .addMock({\n        url: '/wd/hub/session/13521-10219-202/element/0/click',\n        method: 'POST',\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/wd/hub/session/13521-10219-202/element/2/value',\n        method: 'POST',\n        postdata: JSON.stringify({\n          text: 'Nightwatch',\n          value: 'Nightwatch'.split('')\n        }),\n        response: JSON.stringify({\n          value: null\n        })\n      }, true);\n\n    return NightwatchClient.runTests(testsPath, {\n      selenium: {\n        host: 'localhost',\n        port: 4723,\n        start_process: false,\n        use_appium: true\n      },\n      desiredCapabilities: {\n        browserName: ''\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      silent: true,\n      persist_globals: true,\n      globals,\n      output_folder: false\n    }).then(_ => {\n      strictEqual(NightwatchClient.app !== undefined, true);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/cdp/testCdpCommands.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks');\n\nconst mockery = require('mockery');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('cdp commands test', function() {\n  beforeEach(function(done) {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('reset cdp connection after each session is created', function() {\n    const testsPath = [path.join(__dirname, '../../../apidemos/cdp')];\n    let resetConnectionCalled = 0;\n\n    mockery.registerMock('../transport/selenium-webdriver/cdp.js', {\n      getConnection: function(...args) {\n        return Promise.resolve();\n      },\n      resetConnection: function() {\n        resetConnectionCalled += 1;\n      }\n    });\n\n    Mocks\n      .createNewW3CSession({\n        persist: true,\n        browserName: 'chrome',\n        postdata: {\n          capabilities: {firstMatch: [{}], alwaysMatch: {browserName: 'chrome', 'goog:chromeOptions': {}}}\n        }\n      })\n      .navigateTo({url: 'http://localhost', persist: true});\n\n\n    const globals = {\n      calls: 0,\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n\n      reporter(results) {\n        // cdp connection is reset once for each session (two test suites).\n        assert.strictEqual(resetConnectionCalled, 2);\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium_host: null,\n      output: false,\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n\n  it('reset cdp connection after each selenium session is created', function() {\n    const testsPath = [path.join(__dirname, '../../../apidemos/cdp')];\n    let resetConnectionCalled = 0;\n\n    Mocks\n      .createChromeSession({\n        headless: false,\n        times: 2\n      });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/13521-10219-202/url',\n      method: 'POST',\n      postdata: JSON.stringify({\n        url: 'http://localhost'\n      }),\n      response: {\n        value: null\n      },\n      times: 2\n    });\n\n    mockery.registerMock('../transport/selenium-webdriver/cdp.js', {\n      getConnection: function(...args) {\n        return Promise.resolve();\n      },\n      resetConnection: function() {\n        resetConnectionCalled += 1;\n      }\n    });\n\n    const globals = {\n      calls: 0,\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n\n      reporter(results) {\n        // cdp connection is reset once for each session (two test suites).\n        assert.strictEqual(resetConnectionCalled, 2);\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium: {\n        host: 'localhost',\n        port: 10195,\n        start_process: false\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/chrome/testChromeAPI.js",
    "content": "const path = require('path');\nconst common = require('../../../common.js');\nconst MockServer = require('../../../lib/mockserver.js');\nconst NightwatchClient = common.require('index.js');\n\ndescribe('chrome api demos', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    this.server.close(function () {\n      done();\n    });\n  });\n\n  it('run chrome api demo tests basic', function () {\n    const testsPath = path.join(__dirname, '../../../apidemos/chrome/chromeTest.js');\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    MockServer.addMock({\n      url: '/wd/hub/session',\n      method: 'POST',\n      response: JSON.stringify({\n        value: {\n          sessionId: '1352110219202',\n          browserName: 'chrome',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      })\n    });\n\n    return NightwatchClient.runTests(testsPath, {\n      selenium: {\n        host: 'localhost',\n        port: 10195,\n        start_process: false\n      },\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      silent: true,\n      persist_globals: true,\n      globals,\n      output_folder: false\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/cookies/testCookieCommands.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst NightwatchClient = common.require('index.js');\n\ndescribe('cookie demos', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('run cookie api demo tests basic', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/cookies/cookieTests.js');\n    Mocks.cookiesFound({times: 6});\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      calls: 0,\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n\n        assert.strictEqual(globals.calls, 2);\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, {\n      selenium: {\n        host: 'localhost',\n        port: 10195,\n        start_process: false\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      silent: false,\n      persist_globals: true,\n      globals,\n      output_folder: false\n    });\n  });\n\n  it('run cookie api demo tests with socket hang up error', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/cookies/cookieTestsWithError.js');\n    Mocks.cookiesSocketDelay({times: 2});\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.errors, 2);\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, {\n      selenium: {\n        host: 'localhost',\n        port: 10195,\n        start_process: false\n      },\n      webdriver: {\n        start_process: false,\n        timeout_options: {\n          timeout: 50,\n          retry_attempts: 0\n        }\n      },\n      output: false,\n      report_command_errors: true,\n      skip_testcases_on_fail: false,\n      silent: false,\n      persist_globals: true,\n      globals,\n      output_folder: false\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/custom-commands/testCustomCommandAutoInvoke.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('custom commands with auto invoke', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('test custom command using autoInvoke', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/custom-commands/testUsingAutoInvokeCommand.js');\n    Mocks.createNewW3CSession({\n      testName: 'Test Using ES6 Async Custom Commands'\n    });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n      count: 0,\n\n      reporter(results) {\n        \n        if (results.lastError) {\n          throw results.lastError;\n        }\n        assert.strictEqual(this.count, 1);\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: true,\n      silent: false,\n      selenium_host: null,\n      custom_commands_path: [path.join(__dirname, '../../../extra/commands/autoInvoke')],\n      globals\n    }));\n  });\n\n  it('test custom command with returnFn', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/custom-commands/testUsingCommandReturnFn.js');\n    Mocks.createNewW3CSession({\n      testName: 'Test using custom commands with returnFn'\n    });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n      count: 0,\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n        assert.strictEqual(this.count, 2);\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: true,\n      silent: false,\n      selenium_host: null,\n      custom_commands_path: [path.join(__dirname, '../../../extra/commands/returnFn')],\n      globals\n    }));\n  });\n\n});"
  },
  {
    "path": "test/src/apidemos/custom-commands/testCustomCommandSync.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('sync custom commands', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('test sync custom command returning NightwatchAPI as result', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/custom-commands-parallel');\n    Mocks.createNewW3CSession({\n      testName: 'Test Sync Custom Commands returning NightwatchAPI'\n    });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n\n      reporter(results) {\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests({\n      env: 'default',\n      config: 'test/extra/parallelism-customCommandsSync.json'\n    }, Object.assign({}, {\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/custom-commands/testCustomCommandsAsync.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('custom commands with findElements es6 async', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('custom find elements es6 async', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/custom-commands/testUsingES6AsyncCustomCommands.js');\n    Mocks.createNewW3CSession({\n      testName: 'Test Using ES6 Async Custom Commands'\n    });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      silent: true,\n      selenium_host: null,\n      custom_commands_path: [path.join(__dirname, '../../../extra/commands/es6async')],\n      globals\n    }));\n  });\n\n  it('custom assert visible es6 async', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/custom-commands/testUsingAsyncCustomAssert.js');\n    \n    Mocks.createNewW3CSession({\n      testName: 'custom command using assert'\n    });\n\n    Mocks.w3cVisible(true);\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      silent: true,\n      selenium_host: null,\n      custom_commands_path: [path.join(__dirname, '../../../extra/commands/es6async')],\n      globals\n    }));\n  });\n\n  it('custom assert getEmail', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/custom-commands/testUsingCustomGetEmail.js');\n    \n    Mocks.createNewW3CSession({\n      testName: 'custom execute getEmail'\n    });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      silent: true,\n      selenium_host: null,\n      custom_commands_path: [path.join(__dirname, '../../../extra/commands/es6async')],\n      globals\n    }));\n  });\n});"
  },
  {
    "path": "test/src/apidemos/custom-commands/testCustomExecuteAsync.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('custom commands with es6 async', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('custom execute es6 async', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/custom-commands/testUsingCustomExecute.js');\n    Mocks.createNewW3CSession({\n      testName: 'custom execute'\n    });\n    //Mocks.customExecute();\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      selenium_host: null,\n      custom_commands_path: [path.join(__dirname, '../../../extra/commands/es6async')],\n      globals\n    }));\n  });\n\n});\n"
  },
  {
    "path": "test/src/apidemos/custom-commands/testCustomPauseWithNamespacedAlias.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst NightwatchClient = common.require('index.js');\n\ndescribe('custom command with namespaced alias', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    this.server.close(function () {\n      done();\n    });\n  });\n\n  it('test namespaced aliases by running a custom-command', function () {\n    const testsPath = path.join(__dirname, '../../../apidemos/custom-commands/testNamespacedAliases.js');\n    Mocks.createNewW3CSession({\n      testName: 'Test Using Namespaced Aliases'\n    });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError && !results.lastError.message.includes('First argument should be a number')) {\n          throw results.lastError;\n        }\n\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(\n          results.lastError.message,\n          'Error while running \"sampleNamespace.amazingPause\" command: First argument should be a number.'\n        );\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      silent: true,\n      selenium_host: null,\n      custom_commands_path: [path.join(__dirname, '../../../extra/commands')],\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/elements/testElementGlobal.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('element global demos', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('getText on element global instance', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/elements/elementGlobalTest.js');\n    Mocks.elementText();\n    Mocks.tagName('0', 'div');\n    Mocks.visible('0', true, {\n      times: 2\n    });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n\n  it('set use_xpath locate-strategy in element global', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/elements/testGlobalLocateStrategy.js');\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      use_xpath: true\n    }));\n  });\n  \n});\n"
  },
  {
    "path": "test/src/apidemos/elements/testFindElementsEs6CustomCommand.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('find elements in ES6 custom command', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('test custom command', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/elements/findElementsCustomCommand.js');\n\n    const globals = {\n      calls: 0,\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 100,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      skip_testcases_on_fail: false,\n      custom_commands_path: [path.join(__dirname, '../../../extra/commands')],\n      globals\n    }));\n  });\n\n\n});\n"
  },
  {
    "path": "test/src/apidemos/elements/testFindElementsWithPageCommand.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('find elements with page commands', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('test custom command', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/elements/findElementsPageCommands.js');\n\n    const globals = {\n      calls: 0,\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 100,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      skip_testcases_on_fail: false,\n      page_objects_path: [path.join(__dirname, '../../../extra/pageobjects/pages')],\n      globals\n    }));\n  });\n\n\n});\n"
  },
  {
    "path": "test/src/apidemos/ensure/testEnsure.js",
    "content": "const path = require('path');\nconst assert =  require('assert');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('ensure api demos', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('run ensure api demo tests - element selected', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/ensure/ensureTestSelected.js');\n    Mocks.elementSelected();\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      globals\n    }));\n  });\n\n  it('run ensure api demo tests - element not selected', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/ensure/ensureTestNotSelected.js');\n    Mocks.elementNotSelected();\n    Mocks.elementNotSelected();\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 10,\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      globals\n    }));\n  });\n\n  it('run ensure api demo tests failure', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/ensure/ensureTestError.js');\n\n    const globals = {\n      waitForConditionTimeout: 10,\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          assert.strictEqual(results.lastError.name, 'NightwatchAssertError');\n        } else {\n          assert.fail('Should throw an error');\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      skip_testcases_on_fail: false,\n      output: false,\n      globals\n    }));\n  });\n\n});\n"
  },
  {
    "path": "test/src/apidemos/expect-global/testExpect.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('expect(element.<command>) - passed', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('expect(element.command()) - [Pass]', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/expect-global/expect.js');\n    Mocks.elementProperty('0', 'className', {value: ['container', 'div', 'input']});\n    Mocks.elementSelected();\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n\n\n  it('expect(element.command()) - [Fail]', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/expect-global/expect.js');\n    \n    Mocks.elementNotSelected();\n    Mocks.elementProperty('0', 'className', {value: ['container']});\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.failed, 1);\n        assert.strictEqual(results.lastError.name, 'NightwatchAssertError');\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, {\n      selenium: {\n        host: 'localhost',\n        port: 10195,\n        start_process: false\n      },\n      webdriver: {\n        start_process: false,\n        timeout_options: {\n          timeout: 50,\n          retry_attempts: 0\n        }\n      },\n      output: false,\n      report_command_errors: true,\n      skip_testcases_on_fail: false,\n      silent: false,\n      persist_globals: true,\n      globals,\n      output_folder: false\n    });\n  });\n\n  it('stringify deepEqual console output object', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/expect-global/deepEqual.js');\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.failed, 1);\n        assert.strictEqual(results.lastError.name, 'NightwatchAssertError');\n        /* eslint-disable no-control-regex */\n        const cleanErrorMessage = results.lastError.message.replace(/\\x1b\\[[0-9;]*m|\\(.*?\\)/g, '');\n        assert.strictEqual(cleanErrorMessage, 'expected [ { a: 1, b: 4 } ] to deeply equal [ { b: 5 } ] - expected \"[ { b: 5 } ]\" but got: \"[ { a: 1, b: 4 } ]\" ');\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, {\n      selenium: {\n        host: 'localhost',\n        port: 10195,\n        start_process: false\n      },\n      webdriver: {\n        start_process: false,\n        timeout_options: {\n          timeout: 50,\n          retry_attempts: 0\n        }\n      },\n      output: false,\n      report_command_errors: true,\n      skip_testcases_on_fail: false,\n      silent: false,\n      persist_globals: true,\n      globals,\n      output_folder: false\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/firefox/testFirefoxAPI.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst common = require('../../../common.js');\nconst NightwatchClient = common.require('index.js');\n\ndescribe('firefox api demos', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    this.server.close(function () {\n      done();\n    });\n  });\n\n  it('run firefox api demo tests basic', function () {\n    const testsPath = path.join(__dirname, '../../../apidemos/firefox/firefoxTest.js');\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, {\n      selenium: {\n        host: 'localhost',\n        port: 10195,\n        start_process: false\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      silent: true,\n      persist_globals: true,\n      globals,\n      output_folder: false\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/namespaced-api/testNamespacedApi.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('namespaced api tests', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('run basic test with namespaced api', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/namespaced-api/namespacedApiTest.js');\n\n    MockServer\n      .addMock({\n        url: '/wd/hub/session/1352110219202/orientation',\n        statusCode: 200,\n        response: JSON.stringify({\n          value: null\n        }),\n        times: 4\n      })\n      .addMock({\n        url: '/wd/hub/session/1352110219202/execute/sync',\n        method: 'POST',\n        statusCode: 200,\n        response: JSON.stringify({\n          value: null\n        })\n      }, true)\n      .addMock({\n        url: '/wd/hub/session/1352110219202/title',\n        method: 'GET',\n        response: JSON.stringify({\n          value: 'Localhost'\n        }),\n        times: 7\n      });\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      skip_testcases_on_fail: false,\n      output: false,\n      custom_commands_path: [path.join(__dirname, '../../../extra/commands')],\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/navigation/testNavigationCommands.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst MockServer = require('../../../lib/mockserver.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('navigation commands tests', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('navigate tests', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/navigation/navigateTest.js');\n\n    const globals = {\n      calls: 0,\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n\n      onBrowserNavigate(browser) {\n        browser.globals.calls += 1;\n      },\n\n      onBrowserQuit(browser) {\n        browser.globals.calls += 1;\n      },\n\n      reporter(results) {\n        assert.strictEqual(browser.globals.calls, 8);\n\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      skip_testcases_on_fail: false,\n      custom_commands_path: [path.join(__dirname, '../../../extra/commands')],\n      globals\n    }));\n  });\n\n  \n});\n"
  },
  {
    "path": "test/src/apidemos/page-objects/testCommandsReturnType.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('new element api with page objects', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('test custom command', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/page-objects/commandsReturnTypeTest.js');\n\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/click',\n        method: 'POST',\n        response: JSON.stringify({\n          value: null\n        }),\n        times: 2\n      })\n      .addMock({\n        url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/clear',\n        method: 'POST',\n        response: JSON.stringify({\n          value: null\n        }),\n        times: 2\n      })\n      .addMock({\n        url: '/session/13521-10219-202/execute/sync',\n        method: 'POST',\n        response: JSON.stringify({\n          value: true\n        }),\n        times: 4  \n      })\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#helpBtn'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '1'},\n            {'element-6066-11e4-a52e-4f735466cecf': '2'}\n          ]\n        })\n      }, true, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/1/click',\n        method: 'POST',\n        response: JSON.stringify({\n          value: null\n        })\n      }, true, true);\n\n    const globals = {\n      calls: 0,\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 100,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      selenium: {\n        port: null,\n        start_process: false\n      },\n      selenium_host: null,\n      webdriver: {\n        port: 10195,\n        start_process: false\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      page_objects_path: [path.join(__dirname, '../../../extra/pageobjects/pages')],\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/relative-locators/testWithRelativeLocators.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst Mocks = require('../../../lib/command-mocks.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('relative locators demo', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('run relative locators', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/relative-locators/sample-with-relative-locators.js');\n    Mocks.executeSync({\n      value: [\n        {\n          'element-6066-11e4-a52e-4f735466cecf': 'afe6842f-7d0c-4108-9f68-ac5709855960'\n        }\n      ]\n    }, {times: 1});\n\n    Mocks.executeSync({value: true}, {times: 1});\n\n    Mocks.executeSync({\n      value: [\n        {\n          'element-6066-11e4-a52e-4f735466cecf': 'afe6842f-7d0c-4108-9f68-ac5709855960'\n        }\n      ]\n    }, {times: 2});\n\n    Mocks.tagName('afe6842f-7d0c-4108-9f68-ac5709855960', 'input');\n    Mocks.clearElement('afe6842f-7d0c-4108-9f68-ac5709855960');\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/afe6842f-7d0c-4108-9f68-ac5709855960/value',\n      method: 'POST',\n      postdata: {text: 'password', value: ['p', 'a', 's', 's', 'w', 'o', 'r', 'd']},\n      response: {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    });\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 1000,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      output: false,\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n\n  \n});\n"
  },
  {
    "path": "test/src/apidemos/web-elements/testAssert.js",
    "content": "const path = require('path');\nconst assert = require('assert');\n\nconst commandMocks = require('../../../lib/command-mocks');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('element Assertions', function() {\n  beforeEach(function(done) {\n    commandMocks.start(done);\n  });\n\n  afterEach(function(done) {\n    commandMocks.stop(done);\n  });\n\n  it('test assert element command ', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/web-elements/assertionTest.js');\n    commandMocks.w3cVisible();\n    commandMocks.w3cEnabled();\n    commandMocks.w3cVisible(true);\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 0,\n\n      reporter(results) {\n        if (!results.lastError) {\n          assert.fail('should have one failure');\n        }\n        assert.strictEqual(results.passed, 3);\n        assert.strictEqual(results.failed, 1);\n        assert.ok(results.lastError.name === 'NightwatchAssertError');\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      selenium: {\n        port: null,\n        start_process: false\n      },\n      selenium_host: null,\n      webdriver: {\n        port: 10195,\n        start_process: false\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n\n});\n"
  },
  {
    "path": "test/src/apidemos/web-elements/testElementApiWithPageObjects.js",
    "content": "const path = require('path');\nconst MockServer = require('../../../lib/mockserver.js');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('new element api with page objects', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('test custom command', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/web-elements/elementApiWithPageObjects.js');\n\n    MockServer\n      .addMock({\n        url: '/session/13521-10219-202/elements',\n        postdata: {\n          using: 'xpath',\n          value: './/*[text()=\"Web Login\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'},\n            {'element-6066-11e4-a52e-4f735466cecf': '3783b042-7001-0740-a2c0-afdaac732e9f'}\n          ]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'xpath',\n          value: './/*[text()=\"Help\"]'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [{'element-6066-11e4-a52e-4f735466cecf': '2'}]\n        })\n      }, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/0/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#getStarted'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '2'},\n            {'element-6066-11e4-a52e-4f735466cecf': '3'}\n          ]\n        })\n      }, true, true)\n      .addMock({\n        url: '/session/13521-10219-202/element/2/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#getStartedStart'\n        },\n        method: 'POST',\n        response: JSON.stringify({\n          value: [\n            {'element-6066-11e4-a52e-4f735466cecf': '4'},\n            {'element-6066-11e4-a52e-4f735466cecf': '5'},\n            {'element-6066-11e4-a52e-4f735466cecf': '6'}\n          ]\n        })\n      }, true, true);\n\n    const globals = {\n      calls: 0,\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 100,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      selenium: {\n        port: null,\n        start_process: false\n      },\n      selenium_host: null,\n      webdriver: {\n        port: 10195,\n        start_process: false\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      page_objects_path: [path.join(__dirname, '../../../extra/pageobjects/pages')],\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/apidemos/web-elements/testWaitUntil.js",
    "content": "const path = require('path');\nconst assert = require('assert');\n\nconst commandMocks = require('../../../lib/command-mocks');\nconst common = require('../../../common.js');\nconst {settings} = common;\nconst NightwatchClient = common.require('index.js');\n\ndescribe('waitUntil element command', function() {\n  beforeEach(function(done) {\n    commandMocks.start(done);\n  });\n\n  afterEach(function(done) {\n    commandMocks.stop(done);\n  });\n\n  it('test waitUntil element command - passed', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/web-elements/waitUntilTest.js');\n    commandMocks.w3cSelected();\n    commandMocks.w3cVisible();\n    commandMocks.w3cEnabled();\n  \n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 100,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      selenium: {\n        port: null,\n        start_process: false\n      },\n      selenium_host: null,\n      webdriver: {\n        port: 10195,\n        start_process: false\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n\n  it('test waitUntil element command - failed', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/web-elements/waitUntilFailureTest.js');\n    commandMocks.w3cSelected();\n    commandMocks.w3cVisible();\n  \n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 100,\n\n      reporter(results) {\n        if (!results.lastError) {\n          assert.fail('Should result into failure');\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      selenium: {\n        port: null,\n        start_process: false\n      },\n      selenium_host: null,\n      webdriver: {\n        port: 10195,\n        start_process: false\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n\n  it('test waitUntil element command - element not present', function() {\n    const testsPath = path.join(__dirname, '../../../apidemos/web-elements/waitUntilElementNotPresent.js');\n  \n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 120,\n      retryAssertionTimeout: 100,\n\n      reporter(results) {\n        if (!results.lastError) {\n          assert.fail('Should result into failure');\n        }\n        assert.ok(results.lastError.message.includes('not present'), 'err message should be element not present');\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, settings({\n      selenium: {\n        port: null,\n        start_process: false\n      },\n      selenium_host: null,\n      webdriver: {\n        port: 10195,\n        start_process: false\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/cli/testCliRunner.js",
    "content": "const common = require('../../common.js');\nconst mockery = require('mockery');\nconst assert = require('assert');\nconst origPath = require('path');\nconst {constants, rmdirSync} = require('fs');\n\ndelete require.cache['fs'];\ndelete require.cache['path'];\n\ndescribe('Test CLI Runner', function() {\n\n  beforeEach(function() {\n    process.env['ENV_USERNAME'] = 'testuser';\n\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n    mockery.registerMock('./argv-setup.js', {\n      isDefault(option, value) {\n        return value.includes('nightwatch.');\n      },\n\n      getDefault() {\n        return './nightwatch.json';\n      }\n    });\n\n    const config = {\n      src_folders: ['tests'],\n      test_settings: {\n        'default': {\n          silent: true\n        }\n      }\n    };\n\n    const promiseConfig = Promise.resolve({\n      src_folders: ['promiseTests'],\n      test_settings: {\n        default: {\n          silent: true\n        }\n      }\n    });\n\n    mockery.registerMock('package.json', {});\n    mockery.registerMock('./nightwatch.json', config);\n    mockery.registerMock('./nightwatch.conf.js', config);\n    mockery.registerMock('./nightwatchPromise.conf.js', promiseConfig);\n    mockery.registerMock('@nightwatch/nightwatch-inspector', 'crxFile');\n    mockery.registerMock('./websocket-server', class {\n      initSocket() {};\n\n      closeSocket() {};\n    });\n\n    mockery.registerMock('./output_disabled.json', {\n      src_folders: ['tests'],\n      output_folder: false,\n      test_settings: {\n        'default': {\n          silent: true\n        }\n      }\n    });\n\n    mockery.registerMock('./reporter_options.json', {\n      reporter_options: {\n        output_folder: 'output'\n      }\n    });\n\n    mockery.registerMock('./empty.json', {\n      src_folders: 'tests'\n    });\n\n    mockery.registerMock('./null.json', {\n      src_folders: 'tests',\n      test_settings: {\n        'default': {\n          irrelevantProperty: null\n        }\n      }\n    });\n\n    mockery.registerMock('./incorrect.json', {\n      src_folders: 'tests',\n      test_settings: {\n        'default': {}\n      }\n    });\n\n    mockery.registerMock('./globals.json', {\n      extra: {\n        someGlobal: 'test',\n        otherGlobal: 'extra-value'\n      },\n      otherGlobal: 'other-value',\n      inheritedGlobal: 'inherited',\n      overwritten: '1'\n    });\n\n    mockery.registerMock('./settings.json', {\n      src_folders: 'tests',\n      test_settings: {\n        'default': {\n          output: false,\n          disable_colors: true\n        }\n      }\n    });\n    mockery.registerMock('./sauce.json', {\n      src_folders: 'tests',\n      selenium: {\n        start_process: true\n      },\n      end_session_on_fail: true,\n      test_settings: {\n        'default': {},\n        'saucelabs': {\n          selenium: {\n            start_process: false,\n            start_session: false\n          }\n        }\n      }\n    });\n    mockery.registerMock('./selenium_override.json', {\n      src_folders: 'tests',\n      selenium: {\n        start_process: false,\n        start_session: false\n      },\n      test_settings: {\n        'default': {\n          selenium: {\n            start_process: true,\n            start_session: true,\n            server_path: './selenium.jar'\n          }\n        }\n      }\n    });\n\n    mockery.registerMock('./multi_test_paths.json', {\n      src_folders: ['tests1', 'tests2'],\n      test_settings: {\n        'default': {\n          output: false,\n          disable_colors: true\n        }\n      }\n    });\n\n    mockery.registerMock('./custom.json', {\n      src_folders: ['tests'],\n      selenium: {\n        start_process: true,\n        server_path: './selenium.jar'\n      },\n      detailed_output: true,\n      end_session_on_fail: true,\n      test_settings: {\n        'default': {\n          output: false,\n          disable_colors: true,\n          globals: {\n            overwritten: '2',\n            testGlobalOne: 'one',\n            testGlobalTwo: {\n              one: 1,\n              two: {\n                three: '3'\n              }\n            }\n          }\n        },\n        'extra': {\n          username: '${ENV_USERNAME}',\n          credentials: {\n            service: {\n              user: '${ENV_USERNAME}'\n            }\n          },\n          globals: {\n            testGlobalTwo: {\n              two: {\n                three: '5'\n              }\n            }\n          },\n          end_session_on_fail: false,\n          detailed_output: false,\n          selenium: {\n            host: 'other.host'\n          },\n\n          cli_args: {\n            arg1: 'arg1_value',\n            arg2: 'arg2_value'\n          },\n\n          desiredCapabilities: {\n            'test.user': '${ENV_USERNAME}'\n          }\n        }\n      }\n    });\n\n    mockery.registerMock('path', {\n      basename(a) {\n        if (a === './globals.json') {\n          return 'globals';\n        }\n      },\n      dirname(a) {\n        return '';\n      },\n      join: function(a, b) {\n        if (b === './settings.json') {\n          return './settings.json';\n        }\n        if (b === './multi_test_paths.json') {\n          return './multi_test_paths.json';\n        }\n        if (b === './custom.json') {\n          return './custom.json';\n        }\n        if (b === './output_disabled.json') {\n          return './output_disabled.json';\n        }\n        if (b === './empty.json') {\n          return './empty.json';\n        }\n        if (b === './null.json') {\n          return './null.json';\n        }\n        if (b === './incorrect.json') {\n          return './incorrect.json';\n        }\n        if (b === 'demoTest') {\n          return 'demoTest';\n        }\n        if (b === 'demoGroup') {\n          return a + '/demoGroup';\n        }\n        if (b === 'demoGroup1') {\n          return a + '/demoGroup1';\n        }\n        if (b === 'demoGroup2') {\n          return a + '/demoGroup2';\n        }\n        if (b === 'group_doesnotexist') {\n          return a + '/' + b;\n        }\n        if (b === './sauce.json') {\n          return './sauce.json';\n        }\n        if (b === './selenium_override.json') {\n          return './selenium_override.json';\n        }\n        if (b === '../path/to/test') {\n          return process.cwd() + '/path/to/test';\n        }\n        if (b === './doesnotexist.json') {\n          return './doesnotexist.json';\n        }\n        if (b === './extra/globals-err.js') {\n          return './extra/globals-err.js';\n        }\n        if (b === './nightwatchPromise.conf.js') {\n          return './nightwatchPromise.conf.js';\n        }\n\n        return './nightwatch.json';\n      },\n      resolve: function(a) {\n        if (a === '../path/to/test') {\n          return '/path/to/test';\n        }\n\n        return a;\n      },\n      extname(a) {\n        return '.js';\n      },\n      parse(source) {\n        return origPath.parse(source);\n      }\n    });\n  });\n\n  afterEach(function() {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n  });\n\n  function registerNoSettingsJsonMock(){\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(module) {\n        if (module === './settings.json') {\n          throw new Error('Does not exist');\n        }\n\n        if (module === './nightwatch.conf.ts'){\n          return {\n            isFile: function() {\n              return false;\n            }\n          };\n        }\n\n        return {\n          isFile: function() {\n            return true;\n          }\n        };\n      },\n      constants,\n      rmdirSync\n    });\n  }\n\n  it('should have reasonable defaults for CLI arguments', function() {\n    registerNoSettingsJsonMock();\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './nightwatch.json'\n    }).setup();\n\n    assert.deepStrictEqual(runner.settings.src_folders, ['tests']);\n    assert.strictEqual(runner.test_settings.silent, true);\n    assert.strictEqual(runner.test_settings.custom_commands_path, null);\n    assert.strictEqual(runner.test_settings.custom_assertions_path, null);\n    assert.strictEqual(runner.test_settings.output, true);\n    assert.strictEqual(runner.test_settings.tag_filter, undefined);\n    assert.strictEqual(runner.test_settings.skiptags, '');\n    assert.strictEqual(runner.test_settings.filename_filter, undefined);\n    assert.strictEqual(runner.test_settings.skipgroup, '');\n    assert.strictEqual(runner.globals.settings.output_folder, 'tests_output');\n    assert.strictEqual(runner.globals.settings.parallel_mode, false);\n    assert.strictEqual(runner.globals.settings.start_session, true);\n  });\n\n  it('should have defaults for CLI argument for promise config', async () => {\n    registerNoSettingsJsonMock();\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const instance = new CliRunner({\n      config: './nightwatchPromise.conf.js'\n    });\n    const runner = await instance.setupAsync();\n\n    assert.deepStrictEqual(runner.settings.src_folders, ['promiseTests']);\n    assert.strictEqual(runner.test_settings.silent, true);\n    assert.strictEqual(runner.test_settings.custom_commands_path, null);\n    assert.strictEqual(runner.test_settings.custom_assertions_path, null);\n    assert.strictEqual(runner.test_settings.output, true);\n    assert.strictEqual(runner.test_settings.tag_filter, undefined);\n    assert.strictEqual(runner.test_settings.skiptags, '');\n    assert.strictEqual(runner.test_settings.filename_filter, undefined);\n    assert.strictEqual(runner.test_settings.skipgroup, '');\n    assert.strictEqual(runner.globals.settings.output_folder, 'tests_output');\n    assert.strictEqual(runner.globals.settings.parallel_mode, false);\n    assert.strictEqual(runner.globals.settings.start_session, true);\n  });\n\n  it('should override settings with CLI arguments', function() {\n    registerNoSettingsJsonMock();\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './nightwatch.json',\n      verbose: 'yes',\n      output: 'test-output-folder',\n      skiptags: 'home,arctic',\n      tag: 'danger',\n      filter: 'test-filename-filter',\n      skipgroup: 'test-skip-group',\n      timeout: 11,\n      devtools: true,\n      debug: true\n    }).setup();\n\n    assert.strictEqual(runner.argv.devtools, true);\n    assert.strictEqual(runner.argv.debug, true);\n    assert.strictEqual(runner.test_settings.silent, false);\n    assert.strictEqual(runner.test_settings.tag_filter, 'danger');\n    assert.strictEqual(runner.test_settings.skiptags, 'home,arctic');\n    assert.strictEqual(runner.test_settings.filename_filter, 'test-filename-filter');\n    assert.deepStrictEqual(runner.test_settings.skipgroup, ['test-skip-group']);\n    assert.strictEqual(runner.globals.settings.output_folder, 'test-output-folder');\n    assert.strictEqual(runner.test_settings.globals.waitForConditionTimeout, 11);\n    assert.strictEqual(runner.test_settings.globals.retryAssertionTimeout, 11);\n  });\n\n  it('testSetOutputFolder', function() {\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(module) {\n        if (module === './settings.json' || module === './nightwatch.conf.js') {\n          throw new Error('Does not exist');\n        }\n\n        return {\n          isFile: function() {\n            return true;\n          }\n        };\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './output_disabled.json',\n      env: 'default'\n    }).setup();\n\n    assert.strictEqual(runner.settings.output_folder, false);\n  });\n\n  it('testSetOutputFolder using reporterOptions', function(done) {\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(module) {\n        if (module === './settings.json' || module === './nightwatch.conf.js') {\n          throw new Error('Does not exist');\n        }\n\n        return {\n          isFile: function() {\n            return true;\n          }\n        };\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './reporter_options.json',\n      env: 'default'\n    }).setup();\n\n    assert.strictEqual(runner.test_settings.output_folder, 'output');\n\n    done();\n  });\n  \n\n  it('testReadSettingsDeprecated', function(done) {\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(module) {\n        if (module === './settings.json') {\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n        throw new Error('Does not exist');\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './settings.json',\n      env: 'default',\n      output: 'output',\n      verbose: true,\n      skipgroup: 'tobeskipped',\n      filter: 'tests*.js'\n    }).setup();\n\n    assert.deepStrictEqual(runner.test_settings.src_folders, ['tests']);\n    assert.deepStrictEqual(runner.test_settings.skipgroup, ['tobeskipped']);\n    assert.strictEqual(runner.test_settings.output, false);\n    assert.strictEqual(runner.test_settings.silent, false);\n    assert.strictEqual(runner.test_settings.disable_error_log, false);\n    assert.strictEqual(runner.test_settings.disable_colors, true);\n    assert.strictEqual(runner.test_settings.filename_filter, 'tests*.js');\n\n    done();\n  });\n\n \n\n  it('testCustomSettingsFileAndEnvironment', function() {\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(module) {\n        if (module === './custom.json') {\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n        throw new Error('Does not exist');\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './custom.json',\n      env: 'extra'\n    }).setup();\n\n    assert.strictEqual(runner.test_settings.selenium.host, 'other.host');\n    assert.strictEqual(runner.test_settings.detailed_output, false);\n    assert.strictEqual(runner.test_settings.output, false);\n    assert.strictEqual(runner.test_settings.disable_colors, true);\n    assert.strictEqual(runner.test_settings.username, 'testuser');\n    assert.strictEqual(runner.test_settings.credentials.service.user, 'testuser');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['test.user'], 'testuser');\n\n  });\n\n  it('testGetTestSourceSingle', function() {\n    let statCalled = false;\n    let statSyncCalled = false;\n    \n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(file) {\n        if (file === 'demoTest') {\n          statSyncCalled = true;\n\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n\n        if (file === 'demoTest.js' || file === './custom.js') {\n          return {isFile: function() {return true}};\n        }\n\n        throw new Error('Does not exist');\n      },\n      \n\n      stat(file, cb) {\n        if (file === 'demoTest') {\n          statCalled = true;\n        }\n\n        if (file === 'demoTest' || file === 'demoTest.js' || file === './custom.js') {\n          return cb(null, {\n            isFile() {\n              return true;\n            }\n          });\n        }\n\n        throw new Error('Does not exist');\n      },\n\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './custom.json',\n      env: 'default',\n      test: 'demoTest'\n    }).setup();\n\n    const Runner = common.require('runner/runner.js');\n\n    return Runner\n      .readTestSource(runner.test_settings, runner.argv)\n      .then(function(modules) {\n        assert.strictEqual(modules[0], 'demoTest.js');\n        assert.ok(statSyncCalled);\n      });\n  });\n\n  it('testGetTestSourceSingleWithAbsolutePath', function() {\n    const ABSOLUTE_PATH = '/path/to/test';\n    const ABSOLUTE_SRC_PATH = ABSOLUTE_PATH + '.js';\n    let statSyncCalled = false;\n\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(file) {\n        if (file === ABSOLUTE_PATH) {\n          statSyncCalled = true;\n\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n        if (file === ABSOLUTE_SRC_PATH || file === './custom.json') {\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n        throw new Error('Does not exist');\n      },\n\n      stat(file, cb) {\n        if (file === ABSOLUTE_SRC_PATH || file === './custom.js') {\n          return cb(null, {\n            isFile() {\n              return true;\n            }\n          });\n        }\n\n        throw new Error('Does not exist');\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './custom.json',\n      env: 'default',\n      test: ABSOLUTE_PATH\n    }).setup();\n\n    assert.strictEqual(runner.test_settings.detailed_output, true);\n\n    const Runner = common.require('runner/runner.js');\n\n    return Runner\n      .readTestSource(runner.test_settings, runner.argv)\n      .then(function(modules) {\n        assert.strictEqual(modules[0], ABSOLUTE_SRC_PATH);\n        assert.ok(statSyncCalled);\n      });\n  });\n\n  it('testGetTestSourceSingleWithRelativePath', function() {\n    const RELATIVE_PATH = '../path/to/test';\n    const TEST_SRC_PATH = process.cwd() + '/path/to/test.js';\n    let statSyncCalled = false;\n\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      stat(file, cb) {\n        if (file === TEST_SRC_PATH || file === './custom.js') {\n          return cb(null, {\n            isFile() {\n              return true;\n            }\n          });\n        }\n\n        throw new Error('Does not exist');\n      },\n      statSync: function(file) {\n        if (file === RELATIVE_PATH) {\n          statSyncCalled = true;\n\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n        if (file === TEST_SRC_PATH || file === './custom.json') {\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n        throw new Error('Does not exist');\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './custom.json',\n      env: 'default',\n      test: RELATIVE_PATH\n    }).setup();\n\n    const Runner = common.require('runner/runner.js');\n\n    return Runner.readTestSource(runner.test_settings, runner.argv)\n      .then(function(modules) {\n        assert.strictEqual(modules[0], TEST_SRC_PATH);\n        assert.ok(statSyncCalled);\n      });\n  });\n\n  it('testGetTestSourceGroup', function() {\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(module) {\n        switch (module) {\n          case './custom.json':\n          case './multi_test_paths.json':\n            return {\n              isFile: function() {\n                return true;\n              }\n            };\n          case 'tests/demoGroup':\n            return {\n              isDirectory: function() {\n                return true;\n              }\n            };\n        }\n        throw new Error('Does not exist');\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './custom.json',\n      env: 'default',\n      group: 'demoGroup'\n    }).setup();\n\n    const Runner = common.require('runner/runner.js');\n\n    const walker = Runner.getTestSource(runner.test_settings, runner.argv);\n    assert.deepStrictEqual(walker.testSource, ['tests/demoGroup']);\n\n    const otherRunner = new CliRunner({\n      config: './custom.json',\n      env: 'default',\n      group: 'tests/demoGroup'\n    }).setup();\n\n    const walker2 = Runner.getTestSource(otherRunner.test_settings, otherRunner.argv);\n    assert.deepStrictEqual(walker2.testSource, ['tests/demoGroup']);\n\n    const simpleRunner = new CliRunner({\n      config: './custom.json',\n      env: 'default'\n    }).setup();\n\n    const walker3 = Runner.getTestSource(simpleRunner.test_settings, simpleRunner.argv);\n    assert.deepStrictEqual(walker3.testSource, ['tests']);\n\n    const invalidGroupRunner = new CliRunner({\n      config: './custom.json',\n      env: 'default',\n      group: 'group_doesnotexist'\n    }).setup();\n\n    const walker4 = Runner.getTestSource(invalidGroupRunner.test_settings, invalidGroupRunner.argv);\n    assert.deepStrictEqual(walker4.testSource, ['tests/group_doesnotexist']);\n\n    const invalidGroupInMultiSrcRunner = new CliRunner({\n      config: './multi_test_paths.json',\n      env: 'default',\n      group: 'group_doesnotexist'\n    }).setup();\n\n    try {\n      Runner.getTestSource(invalidGroupInMultiSrcRunner.test_settings, invalidGroupInMultiSrcRunner.argv);\n    } catch (ex) {\n      assert.ok(ex.message.includes('No test source specified, please check \"src_folders\" config; src_folders: \"tests1\", \"tests2\"; group(s): \"group_doesnotexist\".'));\n    }\n  });\n\n  it('testGetTestSourceMultipleGroups', function() {\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(module) {\n        switch (module) {\n          case './custom.json':\n          case './multi_test_paths.json':\n            return {\n              isFile: function() {\n                return true;\n              }\n            };\n          case 'tests/demoGroup1':\n          case 'tests/demoGroup2':\n          case 'tests1/demoGroup1':\n          case 'tests1/demoGroup2':\n          case 'tests2/demoGroup2':\n            return {\n              isDirectory: function() {\n                return true;\n              }\n            };\n        }\n        throw new Error('Does not exist');\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './custom.json',\n      env: 'default',\n      group: 'demoGroup1,demoGroup2'\n    }).setup();\n\n    const Runner = common.require('runner/runner.js');\n\n    const walker = Runner.getTestSource(runner.test_settings, runner.argv);\n    assert.deepStrictEqual(walker.testSource, ['tests/demoGroup1', 'tests/demoGroup2']);\n\n    const invalidGroupRunner = new CliRunner({\n      config: './custom.json',\n      env: 'default',\n      group: 'demoGroup1,demoGroup2,group_doesnotexist'\n    }).setup();\n\n    const walker2 = Runner.getTestSource(invalidGroupRunner.test_settings, invalidGroupRunner.argv);\n    assert.deepStrictEqual(walker2.testSource, ['tests/demoGroup1', 'tests/demoGroup2', 'tests/group_doesnotexist']);\n\n    const stripMissingInMultiRunner = new CliRunner({\n      config: './multi_test_paths.json',\n      env: 'default',\n      group: 'demoGroup1,demoGroup2,group_doesnotexist'\n    }).setup();\n\n    const walker3 = Runner.getTestSource(stripMissingInMultiRunner.test_settings, stripMissingInMultiRunner.argv);\n    assert.deepStrictEqual(walker3.testSource, ['tests1/demoGroup1', 'tests1/demoGroup2', 'tests2/demoGroup2']);\n  });\n\n  it('testParseTestSettingsNull', function() {\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(module) {\n        if (module === './null.json') {\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n        throw new Error('Does not exist');\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './null.json',\n      env: 'default'\n    });\n\n    runner.setup();\n    assert.ok(typeof runner.test_settings === 'object');\n    assert.strictEqual(runner.test_settings.irrelevantProperty, null);\n  });\n\n  it('testParseTestSettingsIncorrect', async function() {\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(module) {\n        if (module === './incorrect.json') {\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n        throw new Error('Does not exist');\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    let error;\n    try {\n      await new CliRunner({\n        config: './incorrect.json',\n        env: 'incorrect'\n      }).setupAsync();\n    } catch (err) {\n      error = err;\n    }\n\n    assert.ok(error.message.includes('Invalid testing environment specified: incorrect.'));\n  });\n\n  it('testReadExternalGlobals', function() {\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function(module) {\n        if (module === './custom.json' || module === './globals.json') {\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n        throw new Error('Does not exist');\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './custom.json',\n      env: 'extra'\n    }).setup({\n      globals_path: './globals.json'\n    });\n\n    assert.strictEqual(runner.test_settings.globals.otherGlobal, 'extra-value');\n    assert.strictEqual(runner.test_settings.globals.inheritedGlobal, 'inherited');\n    assert.strictEqual(runner.test_settings.globals.someGlobal, 'test');\n    assert.strictEqual(runner.test_settings.globals.overwritten, '1');\n    assert.strictEqual(runner.test_settings.globals.testGlobalOne, 'one');\n    assert.strictEqual(runner.test_settings.globals.testGlobalTwo.two.three, '5');\n    assert.strictEqual(runner.test_settings.globals.testGlobalTwo.one, 1);\n\n\n    try {\n      new CliRunner({\n        config: './custom.json',\n        env: 'extra'\n      }).setup({\n        globals_path: './doesnotexist.json'\n      });\n    } catch (er) {\n      assert.strictEqual(er.message, 'cannot read external global file using \"./doesnotexist.json\"');\n    }\n\n\n  });\n\n  it('testReadExternalGlobalsError', function() {\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      }, statSync: function(module) {\n        if (module === './custom.json') {\n          return {\n            isFile: function() {\n              return true;\n            }\n          };\n        }\n        throw new Error('Does not exist');\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    try {\n      new CliRunner({\n        config: './custom.json',\n        env: 'extra'\n      }).setup({\n        globals_path: './extra/globals-err.js'\n      });\n    } catch (err) {\n      assert.strictEqual(err.message, 'cannot read external global file using \"./extra/globals-err.js\"');\n    }\n  });\n\n  it('using ES module config file', function() {\n    mockery.deregisterMock('package.json');\n    mockery.registerMock('./nightwatch.conf.cjs', {\n      src_folders: ['tests'],\n      test_settings: {\n        default: {\n          silent: true\n        }\n      }\n    });\n\n    mockery.registerMock('package.json', {\n      type: 'module'\n    });\n\n    registerNoSettingsJsonMock();\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './nightwatch.json'\n    }).setup();\n\n    assert.strictEqual(runner.argv.config, './nightwatch.conf.cjs');\n  });\n\n  it('using Typescript config file', function () {\n    mockery.deregisterMock('package.json');\n    mockery.deregisterMock('fs');\n    mockery.registerMock('./nightwatch.conf.ts', {\n      src_folders: ['tests'],\n      test_settings: {\n        default: {\n          silent: true\n        }\n      }\n    });\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function (module) {\n        if (module === './nightwatch.conf.ts') {\n          return {\n            isFile: function () {\n              return true;\n            }\n          };\n        }\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './nightwatch.json'\n    }).setup();\n\n    assert.strictEqual(runner.argv.config, './nightwatch.conf.ts');\n  });\n\n  it('using no package.json file', function() {\n    mockery.deregisterMock('package.json');\n    mockery.registerMock('package.json');\n\n    registerNoSettingsJsonMock();\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({});\n\n    const config = runner.getLocalConfigFileName();\n    assert.strictEqual(config, './nightwatch.conf.js');\n  });\n\n  it('ios config setup on real device - deviceId passed in args', function() {\n    mockery.registerMock('./ios_config.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        'real.ios': {\n          desiredCapabilities: {\n            browserName: 'safari',\n            platformName: 'iOS',\n            'safari:useSimulator': false\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './ios_config.json',\n      env: 'real.ios',\n      deviceId: '00008030-00024C2C3453402E'\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'real.ios');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['safari:useSimulator'], false);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'safari');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.platformName, 'iOS');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['safari:deviceUDID'], '00008030-00024C2C3453402E');\n  });\n\n  it('ios config setup on real device - deviceId already configured', function() {\n    mockery.registerMock('./ios_config.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        'real.ios': {\n          desiredCapabilities: {\n            browserName: 'safari',\n            platformName: 'iOS',\n            'safari:useSimulator': false,\n            'safari:deviceUDID': '00008030-00024C2C3453402E'\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './ios_config.json',\n      env: 'real.ios'\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'real.ios');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['safari:useSimulator'], false);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'safari');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.platformName, 'iOS');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['safari:deviceUDID'], '00008030-00024C2C3453402E');\n  });\n\n  it('ios config setup on simulator', function() {\n    mockery.registerMock('./ios_config.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        'simulator.ios': {\n          desiredCapabilities: {\n            browserName: 'safari',\n            platformName: 'iOS',\n            'safari:useSimulator': true,\n            'safari:deviceName': 'iPhone 13',\n            'safari:platformVersion': '15.0'\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './ios_config.json',\n      env: 'simulator.ios'\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'simulator.ios');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['safari:useSimulator'], true);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'safari');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.platformName, 'iOS');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['safari:deviceName'], 'iPhone 13');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['safari:platformVersion'], '15.0');\n  });\n\n  it('android config setup on emulator - for chrome', function() {\n    mockery.registerMock('./android_config.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        'android.chrome': {\n          desiredCapabilities: {\n            real_mobile: false,\n            avd: 'nightwatch-android-11',\n            browserName: 'chrome',\n            'goog:chromeOptions': {\n              androidPackage: 'com.android.chrome'\n            }\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './android_config.json',\n      env: 'android.chrome'\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'android.chrome');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.real_mobile, false);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.avd, 'nightwatch-android-11');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'chrome');\n    assert.ok('goog:chromeOptions' in runner.test_settings.desiredCapabilities);\n    assert.strictEqual(runner.test_settings.desiredCapabilities['goog:chromeOptions'].androidPackage, 'com.android.chrome');\n  });\n\n  it('android config setup on emulator - for firefox', function() {\n    mockery.registerMock('./android_config.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        'android.firefox': {\n          desiredCapabilities: {\n            real_mobile: false,\n            avd: 'nightwatch-android-11',\n            browserName: 'firefox',\n            'moz:firefoxOptions': {\n              androidPackage: 'org.mozilla.firefox'\n            }\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './android_config.json',\n      env: 'android.firefox'\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'android.firefox');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.real_mobile, false);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.avd, 'nightwatch-android-11');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'firefox');\n    assert.ok('moz:firefoxOptions' in runner.test_settings.desiredCapabilities);\n    assert.strictEqual(runner.test_settings.desiredCapabilities['moz:firefoxOptions'].androidPackage, 'org.mozilla.firefox');\n  });\n\n  it('android config setup on real device - for chrome', function() {\n    mockery.registerMock('./android_config.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        'android.chrome': {\n          desiredCapabilities: {\n            real_mobile: true,\n            avd: 'nightwatch-android-11',\n            browserName: 'chrome',\n            'goog:chromeOptions': {\n              androidPackage: 'com.android.chrome',\n              androidDeviceSerial: 'ZD2222W62Y'\n            }\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './android_config.json',\n      env: 'android.chrome'\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'android.chrome');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.real_mobile, true);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.avd, 'nightwatch-android-11');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'chrome');\n    assert.ok('goog:chromeOptions' in runner.test_settings.desiredCapabilities);\n    assert.strictEqual(runner.test_settings.desiredCapabilities['goog:chromeOptions'].androidPackage, 'com.android.chrome');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['goog:chromeOptions'].androidDeviceSerial, 'ZD2222W62Y');\n  });\n\n  it('android config setup on real device - for firefox', function() {\n    mockery.registerMock('./android_config.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        'android.firefox': {\n          desiredCapabilities: {\n            real_mobile: true,\n            avd: 'nightwatch-android-11',\n            browserName: 'firefox',\n            'moz:firefoxOptions': {\n              androidPackage: 'org.mozilla.firefox',\n              androidDeviceSerial: 'ZD2222W62Y'\n            }\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './android_config.json',\n      env: 'android.firefox'\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'android.firefox');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.real_mobile, true);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.avd, 'nightwatch-android-11');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'firefox');\n    assert.ok('moz:firefoxOptions' in runner.test_settings.desiredCapabilities);\n    assert.strictEqual(runner.test_settings.desiredCapabilities['moz:firefoxOptions'].androidPackage, 'org.mozilla.firefox');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['moz:firefoxOptions'].androidDeviceSerial, 'ZD2222W62Y');\n  });\n\n  it('android config setup on real device - for chrome - deviceId passed in args', function() {\n    mockery.registerMock('./android_config.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        'android.chrome': {\n          desiredCapabilities: {\n            real_mobile: true,\n            avd: 'nightwatch-android-11',\n            browserName: 'chrome',\n            'goog:chromeOptions': {\n              androidPackage: 'com.android.chrome'\n            }\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './android_config.json',\n      env: 'android.chrome',\n      deviceId: 'ZD2222W62Y'\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'android.chrome');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.real_mobile, true);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.avd, 'nightwatch-android-11');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'chrome');\n    assert.ok('goog:chromeOptions' in runner.test_settings.desiredCapabilities);\n    assert.strictEqual(runner.test_settings.desiredCapabilities['goog:chromeOptions'].androidPackage, 'com.android.chrome');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['goog:chromeOptions'].androidDeviceSerial, 'ZD2222W62Y');\n  });\n\n  it('android config setup on real device - for firefox - deviceId passed in args', function() {\n    mockery.registerMock('./android_config.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        'android.firefox': {\n          desiredCapabilities: {\n            real_mobile: true,\n            avd: 'nightwatch-android-11',\n            browserName: 'firefox',\n            'moz:firefoxOptions': {\n              androidPackage: 'org.mozilla.firefox'\n            }\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './android_config.json',\n      env: 'android.firefox',\n      deviceId: 'ZD2222W62Y'\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'android.firefox');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.real_mobile, true);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.avd, 'nightwatch-android-11');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'firefox');\n    assert.ok('moz:firefoxOptions' in runner.test_settings.desiredCapabilities);\n    assert.strictEqual(runner.test_settings.desiredCapabilities['moz:firefoxOptions'].androidPackage, 'org.mozilla.firefox');\n    assert.strictEqual(runner.test_settings.desiredCapabilities['moz:firefoxOptions'].androidDeviceSerial, 'ZD2222W62Y');\n  });\n\n  describe('Test \\'list-files\\' flag', () => { \n    it('output list of files - default environment', async () => {\n      const testsPath = [origPath.join(__dirname, origPath.join('..', '..', 'sampletests', 'simple', 'test', 'sample.js'))];\n      const consoleData = [];\n      const listFileOutput = JSON.stringify({\n        default: testsPath\n      });\n  \n      const origConsoleLog = console.log;\n  \n      console.log = function (data) {\n        consoleData.push(data);\n      };\n  \n      mockery.registerMock('./runner/cli/argv-setup.js', {\n        argv: {\n          _: testsPath,\n          'list-files': true\n        }\n      });\n      const NwClient = common.require('index.js');\n      await NwClient.cli();\n      assert.deepStrictEqual(listFileOutput, consoleData[0]);\n      console.log = origConsoleLog;\n    });\n\n    it('output list of files - chrome environment', async () => {\n      const testsPath = [origPath.join(__dirname, origPath.join('..', '..', 'sampletests', 'simple', 'test', 'sample.js'))];\n      const consoleData = [];\n      const listFileOutput = JSON.stringify({\n        chrome: testsPath\n      });\n  \n      const origConsoleLog = console.log;\n  \n      console.log = function (data) {\n        consoleData.push(data);\n      };\n  \n      mockery.registerMock('./runner/cli/argv-setup.js', {\n        argv: {\n          _: testsPath,\n          env: 'chrome',\n          'list-files': true\n        }\n      });\n      const NwClient = common.require('index.js');\n      await NwClient.cli();\n      assert.deepStrictEqual(listFileOutput, consoleData[0]);\n      console.log = origConsoleLog;\n    });\n  });\n\n\n  it('Nightwatch Inspector - By default Chrome in debug mode run serially', function() {\n    mockery.registerMock('./nightwatch_inspector.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        chrome: {\n          desiredCapabilities: {\n            browserName: 'chrome'\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './nightwatch_inspector.json',\n      env: 'chrome',\n      debug: true\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'chrome');\n    assert.strictEqual(runner.test_settings.parallel_mode, false);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'chrome');\n  });\n\n  it('Nightwatch Inspector - parallel argument enables running Chrome in debug mode parallelly', function() {\n    mockery.registerMock('./nightwatch_inspector.json', {\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false\n        },\n\n        chrome: {\n          desiredCapabilities: {\n            browserName: 'chrome'\n          }\n        }\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n\n    const runner = new CliRunner({\n      config: './nightwatch_inspector.json',\n      env: 'chrome',\n      debug: true,\n      parallel: true\n    }).setup();\n\n    assert.strictEqual(runner.argv.env, 'chrome');\n    assert.strictEqual(runner.argv.serial, undefined);\n    assert.strictEqual(runner.argv.parallel, true);\n    assert.strictEqual(runner.test_settings.desiredCapabilities.browserName, 'chrome');\n  });\n\n});\n"
  },
  {
    "path": "test/src/cli/testCliRunnerGenerate.js",
    "content": "const common = require('../../common.js');\nconst mockery = require('mockery');\nconst assert = require('assert');\n\ndescribe('Test CLI Runner Generate', function() {\n\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n    mockery.registerMock('./argv-setup.js', {\n      isDefault(option, value) {\n        return value.includes('nightwatch.');\n      },\n\n      getDefault() {\n        return './nightwatch.json';\n      }\n    });\n\n    mockery.registerMock('@nightwatch/nightwatch-inspector', 'crxFile');\n    mockery.registerMock('./websocket-server', class {\n      initSocket() {};\n\n      closeSocket() {};\n    });\n  });\n\n  afterEach(function() {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n  });\n\n  it('test start CLI Runner with no config file', function () {\n    let configData;\n    const {constants, rmdirSync, readFileSync} = require('fs');\n    const path = require('path');\n    const tplData = readFileSync(path.resolve('lib/runner/cli/nightwatch.conf.ejs')).toString();\n\n    const os = require('os');\n    mockery.registerMock('os', {\n      platform: function() {\n        return 'win';\n      },\n      constants: os.constants,\n      homedir: os.homedir,\n      release: os.release,\n      cpus: os.cpus\n    });\n\n    mockery.registerMock('fs', {\n      existsSync() {\n        return false;\n      },\n      statSync: function (fileName) {\n        if (fileName.endsWith('/nightwatch.conf.js')) {\n          return {\n            isFile: function () {\n              return false;\n            }\n          };\n        }\n\n        if (fileName.endsWith('/nightwatch.json')) {\n          return {\n            isFile: function () {\n              return false;\n            }\n          };\n        }\n      },\n\n      readFileSync: function(fileName) {\n        return {\n          toString: function () {\n            return tplData;\n          }\n        };\n      },\n\n      writeFileSync: function (destFileName, content) {\n        assert.strictEqual(destFileName, path.join(process.cwd(), 'nightwatch.conf.js'));\n        configData = eval(content);\n        mockery.registerMock(path.join(process.cwd(), 'nightwatch.conf.js'), configData);\n\n        assert.strictEqual(typeof configData.safari, 'undefined');\n\n        assert.deepStrictEqual(configData.test_settings.chrome, {\n          desiredCapabilities: {\n            browserName: 'chrome',\n            'goog:chromeOptions': {\n              args: [],\n              w3c: true\n            }\n          },\n\n          webdriver: {\n            start_process: true,\n            server_path: '',\n            cli_args: []\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings.firefox, {\n          desiredCapabilities: {\n            browserName: 'firefox',\n            acceptInsecureCerts: true,\n            'moz:firefoxOptions': {\n              args: []\n            }\n          },\n          webdriver: {\n            start_process: true,\n            server_path: '',\n            cli_args: []\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings.browserstack, {\n          desiredCapabilities: {\n            'bstack:options': {\n              userName: '${BROWSERSTACK_USERNAME}',\n              accessKey: '${BROWSERSTACK_ACCESS_KEY}'\n            }\n          },\n\n          selenium: {\n            host: 'hub.browserstack.com',\n            port: 443\n          },\n\n          disable_error_log: true,\n          webdriver: {\n            timeout_options: {\n              timeout: 60000,\n              retry_attempts: 3\n            },\n            keep_alive: true,\n            start_process: false\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings['browserstack.local'], {\n          extends: 'browserstack',\n          desiredCapabilities: {\n            'browserstack.local': true\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings['browserstack.local_firefox'], {\n          extends: 'browserstack.local',\n          desiredCapabilities: {\n            browserName: 'firefox'\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings['browserstack.local_chrome'], {\n          extends: 'browserstack.local',\n          desiredCapabilities: {\n            browserName: 'chrome'\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings['browserstack.chrome'], {\n          extends: 'browserstack',\n          desiredCapabilities: {\n            browserName: 'chrome',\n            chromeOptions: {\n              w3c: true\n            }\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings['browserstack.ie'], {\n          extends: 'browserstack',\n          desiredCapabilities: {\n            browserName: 'internet explorer',\n            browserVersion: '11.0'\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings.saucelabs, {\n          desiredCapabilities: {\n            'sauce:options': {\n              username: '${SAUCE_USERNAME}',\n              accessKey: '${SAUCE_ACCESS_KEY}',\n              screenResolution: '1280x1024'\n              // https://docs.saucelabs.com/dev/cli/sauce-connect-proxy/#--region\n              // region: 'us-west-1'\n              // https://docs.saucelabs.com/dev/test-configuration-options/#tunnelidentifier\n              // parentTunnel: ''\n              // tunnelIdentifier: ''\n            }\n          },\n\n          selenium: {\n            host: 'ondemand.saucelabs.com',\n            port: 443\n          },\n\n          disable_error_log: false,\n          webdriver: {\n            start_process: false\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings['saucelabs.chrome'], {\n          extends: 'saucelabs',\n          desiredCapabilities: {\n            browserName: 'chrome',\n            browserVersion: 'latest',\n            javascriptEnabled: true,\n            acceptSslCerts: true,\n            timeZone: 'London',\n            chromeOptions: {\n              w3c: true\n            }\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings['saucelabs.firefox'], {\n          extends: 'saucelabs',\n          desiredCapabilities: {\n            browserName: 'firefox',\n            browserVersion: 'latest',\n            javascriptEnabled: true,\n            acceptSslCerts: true,\n            timeZone: 'London'\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings['cucumber-js'], {\n          src_folders: ['examples/cucumber-js/features/step_definitions'],\n          test_runner: {\n            type: 'cucumber',\n            options: {\n              feature_path: 'node_modules/nightwatch/examples/cucumber-js/*/*.feature'\n            }\n          }\n        });\n\n        assert.deepStrictEqual(configData.test_settings.selenium_server, {\n          selenium: {\n            start_process: true,\n            port: 4444,\n            command: 'standalone',\n            server_path: '',\n            cli_args: {\n            }\n          },\n          webdriver: {\n            start_process: false,\n            default_path_prefix: '/wd/hub'\n          }\n        });\n      },\n      constants,\n      rmdirSync\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const ieRunner = new CliRunner({\n      config: './nightwatch.json',\n      env: 'browserstack.ie'\n    }).setup();\n\n    assert.strictEqual(ieRunner.argv.config, path.join(process.cwd(), 'nightwatch.conf.js'));\n\n    const chromeLocalRunner = new CliRunner({\n      config: './nightwatch.json',\n      env: 'browserstack.local_chrome'\n    }).setup();\n\n    assert.deepStrictEqual(ieRunner.test_settings.desiredCapabilities, {\n      browserName: 'internet explorer',\n      browserVersion: '11.0',\n      'bstack:options': {\n        userName: '${BROWSERSTACK_USERNAME}',\n        accessKey: '${BROWSERSTACK_ACCESS_KEY}'\n      }\n    });\n    assert.deepStrictEqual(chromeLocalRunner.test_settings.desiredCapabilities, {\n      browserName: 'chrome',\n      'browserstack.local': true,\n      'bstack:options': {\n        userName: '${BROWSERSTACK_USERNAME}',\n        accessKey: '${BROWSERSTACK_ACCESS_KEY}'\n      }\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/cli/testCliRunnerMocha.js",
    "content": "const common = require('../../common.js');\nconst mockery = require('mockery');\nconst assert = require('assert');\nconst path = require('path');\n\ndescribe('test CLI Runner Mocha', function() {\n  beforeEach(function() {\n    process.env['ENV_USERNAME'] = 'testuser';\n\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n\n    mockery.registerMock('package.json', {});\n    mockery.registerMock('./argv-setup.js', {\n      isDefault(option, value) {\n        return value.includes('nightwatch.');\n      },\n\n      getDefault() {\n        return './nightwatch.json';\n      }\n    });\n\n    mockery.registerMock('path', {\n      resolve: function(a) {\n        return a;\n      },\n      extname: path.extname,\n      join: path.join\n    });\n\n    mockery.registerMock('./folder-walk.js', class Walk {\n      readTestSource(source, settings, cb) {\n        return Promise.resolve([\n          'test1.js',\n          'test2.js'\n        ]);\n      }\n    });\n    mockery.registerMock('../../index.js', {\n      client(settings) {\n        return {\n          api: {},\n          settings: {}\n        };\n      }\n    });\n\n  });\n\n  afterEach(function() {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n  });\n\n  it('testRunWithMochaDefaults', function() {\n    const testFiles = [];\n\n    const defaultOptions = {timeout: 20000, reporterOptions: {}};\n    mockery.registerMock('./withmocha.json', {\n      src_folders: ['tests'],\n      output_folder: false,\n      test_settings: {\n        'default': {\n          silent: true\n        }\n      },\n      test_runner: 'mocha'\n    });\n\n    createMockedMocha(function(options) {\n      assert.deepStrictEqual(options, defaultOptions);\n    }, testFiles);\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './withmocha.json',\n      env: 'default',\n      reporter: 'junit'\n    }).setup();\n\n    return runner.runTests().then(function() {\n      assert.deepStrictEqual(testFiles, ['test1.js', 'test2.js']);\n    });\n  });\n\n  it('testRunWithMocha - parallelism', function() {\n\n    const ChildProcess = common.require('runner/concurrency/child-process.js');\n    let childProcessCreated = false;\n    class ChildProcessMock extends ChildProcess {\n      run(colors, type) {\n        childProcessCreated = true;\n        assert.strictEqual(colors.length, 4);\n        assert.strictEqual(type, 'workers');\n        assert.deepStrictEqual(Object.keys(this._events), ['message']);\n  \n        return Promise.resolve(0);\n      }\n    }\n  \n    mockery.registerMock('./child-process.js', ChildProcessMock);\n  \n    mockery.registerMock('./withmocha.json', {\n      src_folders: ['tests'],\n      output_folder: false,\n      use_child_process: false,\n      test_settings: {\n        'default': {\n          silent: true\n        }\n      },\n      test_runner: 'mocha'\n    });\n\n  \n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './withmocha.json',\n      env: 'default',\n      reporter: 'junit',\n      parallel: true\n    }).setup();\n  \n    return runner.runTests().then(function() {\n      assert.ok(childProcessCreated, 'mocha runner with parallel threads should use child process');\n    });\n  });\n\n  it('testRunWithMochaPerEnvironment', function() {\n    const testFiles = [];\n    const defaultOptions = {timeout: 20000, reporterOptions: {}};\n\n    mockery.registerMock('./withmocha.json', {\n      src_folders: ['tests'],\n      output_folder: false,\n      test_settings: {\n        'default': {\n          silent: true\n        },\n        mochatests: {\n          test_runner: 'mocha'\n        }\n      },\n      test_runner: 'default'\n    });\n\n    createMockedMocha(function(options) {\n      assert.deepStrictEqual(options, defaultOptions);\n    }, testFiles);\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './withmocha.json',\n      env: 'mochatests',\n      reporter: 'junit'\n    }).setup();\n\n    return runner.runTests().then(function() {\n      assert.deepStrictEqual(testFiles, ['test1.js', 'test2.js']);\n    });\n  });\n\n  it('testRunWithMochaCustomOpts', function() {\n    const testFiles = [];\n\n    const defaultOptions = {\n      ui: 'tdd',\n      timeout: 20000,\n      reporterOptions: {}\n    };\n\n    mockery.registerMock('./withmocha.json', {\n      src_folders: ['tests'],\n      output_folder: false,\n      test_settings: {\n        'default': {\n          silent: true\n        }\n      },\n      test_runner: {\n        type: 'mocha',\n        options: {\n          ui: 'tdd'\n        }\n      }\n    });\n\n    createMockedMocha(function(options) {\n      assert.deepStrictEqual(options, defaultOptions);\n    }, testFiles);\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './withmocha.json',\n      env: 'default',\n      reporter: 'junit'\n    }).setup();\n\n    return runner.runTests().then(function() {\n      assert.deepStrictEqual(testFiles, ['test1.js', 'test2.js']);\n    });\n  });\n\n  it('testRunWithMochaReporterOptions', function() {\n    const testFiles = [];\n\n    const mochaOptions = {\n      timeout: 20000, \n      reporterOptions: {\n        reportDir: 'html-dir'\n      },\n      reporter: 'mochawesome'\n    };\n\n\n    mockery.registerMock('mochawesome', {});\n\n    mockery.registerMock('./withmochaReportOptions.json', {\n      src_folders: ['tests'],\n      output_folder: false,\n      test_settings: {\n        'default': {\n          silent: true\n        }\n      },\n      reporter_options: {\n        reportDir: 'html-dir'\n      },\n      test_runner: {\n        type: 'mocha',\n        options: {\n          reporter: 'mochawesome'\n        }\n      }\n    });\n\n    createMockedMocha(function(options) {\n      assert.deepStrictEqual(options, mochaOptions);\n    }, testFiles);\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './withmochaReportOptions.json',\n      env: 'default',\n      reporter: 'junit'\n    }).setup();\n\n    return runner.runTests().then(function() {\n      assert.deepStrictEqual(testFiles, ['test1.js', 'test2.js']);\n    });\n  });\n\n});\n\n\nfunction createMockedMocha(assertionFn = function() {}, testFiles = []) {\n  function Mocha(options) {\n    this.suite = {\n      on() {}\n    };\n    assertionFn(options);\n  }\n\n  Mocha.prototype = {\n    addFile: function(file) {\n      testFiles.push(file);\n    },\n    run: function(cb) {\n      cb(null);\n    }\n  };\n\n  Mocha.Runner = function() {\n    this.suite = {};\n  };\n\n  Mocha.Runner.prototype = {\n    runSuite() {},\n    run(fn) {}\n  };\n\n  mockery.registerMock('mocha', Mocha);\n}\n"
  },
  {
    "path": "test/src/cli/testDemoTypescriptFile.js",
    "content": "const path = require('path');\nconst MockServer = require('../../lib/mockserver.js');\nconst common = require('../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst Utils = common.require('utils');\n\ndescribe('Typescript demos', function () {\n  const oldLoadTSNode = Utils.loadTSNode;\n  let tsNode;\n\n  before(function(done) {\n    Utils.loadTSNode = function(projectTsFile) {\n      \n      tsNode = require('ts-node').register({\n        esm: false,\n        project: projectTsFile\n      });\n      \n    };\n    done();\n  });\n\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    this.server.close(function () {\n      done();\n    });\n  });\n\n  after(function(done) {\n    if (tsNode) {\n      tsNode.enabled(false);\n    }\n    Utils.loadTSNode = oldLoadTSNode;\n    done();\n  });\n\n  it('run basic typescript tests', function () {\n    this.timeout(5000);\n    const testsPath = path.join(__dirname, '../../typescript-tests/demo.ts');\n    const originalCwd = process.cwd();\n    process.chdir(path.join(__dirname, '../../typescript-tests'));\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return NightwatchClient.runTests(testsPath, {\n      selenium: {\n        host: 'localhost',\n        port: 10195,\n        start_process: false\n      },\n      output: false,\n      skip_testcases_on_fail: false,\n      silent: true,\n      persist_globals: true,\n      globals,\n      output_folder: false\n    }).then(() => {\n      process.chdir(originalCwd);\n    }).catch(() => {\n      process.chdir(originalCwd);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/cli/testParallelExecution.js",
    "content": "const EventEmitter = require('events');\nconst mockery = require('mockery');\nconst path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test Parallel Execution', function() {\n  const workerPoolArgv = [];\n  const taskArgv = [];\n  const allArgs = [];\n  const allOpts = [];\n\n  this.timeout(10000);\n  let workerCount;\n\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnUnregistered: false});\n\n    mockery.registerMock('package.json', {});\n    mockery.registerMock('child_process', {\n      spawn: function(path, args, opts) {\n        allArgs.push(args);\n        allOpts.push(opts);\n\n        class Stdout extends EventEmitter {}\n        class Stderr extends EventEmitter {}\n\n        class ChildProcess extends EventEmitter {\n          constructor() {\n            super();\n\n            this.stdout = new Stdout();\n            this.stderr = new Stderr();\n\n            setTimeout(function() {\n              this.emit('close');\n              this.emit('exit', 0);\n            }.bind(this), 11);\n          }\n        }\n\n        return new ChildProcess();\n      }\n    });\n    mockery.registerMock('./worker-process.js', class WorkerProcess extends EventEmitter {\n      constructor(args, settings, maxWorkerCount) {\n        super();\n\n        this.tasks = [];\n        this.index = 0;\n        workerCount = maxWorkerCount;\n        workerPoolArgv.push(args);\n      }\n\n      addTask({argv}) {\n        \n        taskArgv.push(argv);\n        this.tasks.push(Promise.resolve());\n        Promise.resolve();\n      }\n    });\n\n    const {platform, constants, homedir, release, type, tmpdir} = require('os');\n    mockery.registerMock('os', {\n      cpus: function() {\n        return [0, 1];\n      },\n      platform,\n      constants,\n      homedir,\n      release,\n      type,\n      tmpdir\n    });\n  });\n\n  afterEach(function() {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n    allArgs.length = 0;\n    workerPoolArgv.length = 0;\n    taskArgv.length = 0;\n    allOpts.length = 0;\n    process.env.__NIGHTWATCH_PARALLEL_MODE = null;\n  });\n\n\n  it('testParallelExecution - child-process', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const originalCwd = process.cwd();\n    process.chdir(path.join(__dirname, '../../extra/'));\n    const runner = new CliRunner({\n      config: './nightwatch.json',\n      env: 'default,mixed',\n      reporter: 'junit'\n    });\n    runner.setup({\n      use_child_process: true\n    });\n    assert.ok(runner.parallelMode());\n    assert.strictEqual(runner.testEnv, 'default,mixed');\n    assert.deepStrictEqual(runner.availableTestEnvs, ['default', 'mixed']);\n\n    return runner.runTests().then(_ => {\n      assert.ok(runner.parallelMode());\n      assert.strictEqual(runner.concurrency.globalExitCode, 0);\n      assert.strictEqual(allArgs.length, 2);\n      assert.ok(allArgs[0].join(' ').includes('--env default --parallel-mode'));\n      assert.ok(allArgs[1].join(' ').includes('--env mixed --parallel-mode'));\n\n      process.chdir(originalCwd);\n    });\n  });\n\n  it('testParallelExecution -- worker', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const originalCwd = process.cwd();\n    process.chdir(path.join(__dirname, '../../extra/'));\n\n    const runner = new CliRunner({\n      config: './nightwatch.json',\n      env: 'default,mixed',\n      reporter: 'junit'\n    });\n\n    runner.setup({\n      use_child_process: false\n    });\n\n    assert.ok(runner.parallelMode());\n    assert.strictEqual(runner.testEnv, 'default,mixed');\n    assert.deepStrictEqual(runner.availableTestEnvs, ['default', 'mixed']);\n\n    return runner.runTests().then(_ => {\n      assert.ok(runner.parallelMode());\n      assert.strictEqual(runner.concurrency.globalExitCode, 0);\n      assert.strictEqual(workerPoolArgv.length, 1);\n      assert.ok(workerPoolArgv[0].join(' ').includes('--parallel-mode'));\n      assert.strictEqual(taskArgv.length, 2);\n      assert.strictEqual(taskArgv[0].env, 'default');\n      assert.strictEqual(taskArgv[1].env, 'mixed');\n      process.chdir(originalCwd);\n    });\n  });\n\n\n  it('test parallel execution with workers defaults -- child process', function(){\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism.json')\n    });\n    runner.setup({\n      use_child_process: true\n    });\n    runner.test_settings.globals.retryAssertionTimeout = 10;\n    runner.test_settings.globals.waitForConditionTimeout = 10;\n    runner.test_settings.globals.waitForConditionPollInterval = 9;\n    assert.ok(runner.test_settings.test_workers);\n\n    return runner.runTests().then(_ => {\n      assert.strictEqual(allArgs.length, 4);\n      assert.strictEqual(runner.concurrency.globalExitCode, 0);\n    });\n  });\n\n  it('test parallel execution with workers defaults -- worker thread', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism.json')\n    });\n\n    runner.setup({\n      use_child_process: false\n    });\n    runner.test_settings.globals.retryAssertionTimeout = 10;\n    runner.test_settings.globals.waitForConditionTimeout = 10;\n    runner.test_settings.globals.waitForConditionPollInterval = 9;\n    assert.ok(runner.test_settings.test_workers);\n\n    return runner.runTests().then(_ => {\n      assert.strictEqual(taskArgv.length, 4);\n      assert.strictEqual(runner.concurrency.globalExitCode, 0);\n    });\n  });\n\n  it('testParallelExecutionSameEnv - child-process', function() {\n    const originalCwd = process.cwd();\n    process.chdir(path.join(__dirname, '../../extra/'));\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './nightwatch.json',\n      reporter: 'junit',\n      env: 'mixed,mixed'\n    });\n    runner.setup({\n      use_child_process: true\n    });\n    assert.ok(runner.parallelMode());\n    assert.strictEqual(runner.testEnv, 'mixed,mixed');\n    assert.deepStrictEqual(runner.availableTestEnvs, ['default', 'mixed']);\n\n    return runner.runTests().then(_ => {\n      assert.strictEqual(allArgs.length, 2);\n      assert.ok(allArgs[0].join(' ').includes('--env mixed --parallel-mode'));\n      assert.ok(allArgs[1].join(' ').includes('--env mixed --parallel-mode'));\n      process.chdir(originalCwd);\n    });\n  });\n\n  it('testParallelExecutionSameEnv - worker threads', function() {\n    const originalCwd = process.cwd();\n    process.chdir(path.join(__dirname, '../../extra/'));\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './nightwatch.json',\n      reporter: 'junit',\n      env: 'mixed,mixed'\n    });\n\n    runner.setup({\n      use_child_process: false\n    });\n\n    assert.ok(runner.parallelMode());\n    assert.strictEqual(runner.testEnv, 'mixed,mixed');\n    assert.deepStrictEqual(runner.availableTestEnvs, ['default', 'mixed']);\n\n    return runner.runTests().then(_ => {\n      assert.strictEqual(taskArgv.length, 2);\n      assert.strictEqual(taskArgv[0].env, 'mixed');\n      assert.strictEqual(taskArgv[1].env, 'mixed');\n      process.chdir(originalCwd);\n    });\n  });\n\n\n  it('testParallelExecutionWithWorkersAuto - child process', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-auto.json')\n    });\n    runner.setup({\n      use_child_process: true\n    });\n    assert.deepStrictEqual(runner.test_settings.test_workers, {\n      enabled: true,\n      workers: 'auto'\n    });\n\n    return runner.runTests().then(_ => {\n      assert.strictEqual(allArgs.length, 4);\n    });\n  });\n\n  it('testParallelExecutionWithWorkersAuto - worker threads', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-auto.json')\n    });\n\n    runner.setup({\n      use_child_process: false\n    });\n    assert.deepStrictEqual(runner.test_settings.test_workers, {\n      enabled: true,\n      workers: 'auto'\n    });\n\n    return runner.runTests().then(_ => {\n      assert.strictEqual(taskArgv.length, 4);\n    });\n  });\n\n  it('testParallelExecutionWithWorkers and multiple environments - child process', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-auto.json'),\n      env: 'default,default'\n    });\n\n    runner.setup({\n      use_child_process: true\n    });\n    assert.strictEqual(runner.test_settings.test_workers.enabled, true);\n    assert.ok(runner.test_settings.testWorkersEnabled);\n  });\n\n  it('testParallelExecutionWithWorkers and multiple environments - worker threads', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-auto.json'),\n      env: 'default,default'\n    });\n\n    runner.setup({\n      use_child_process: false\n    });\n    assert.strictEqual(runner.test_settings.test_workers.enabled, true);\n    assert.ok(runner.test_settings.testWorkersEnabled);\n  });\n\n\n  it('test parallel execution with workers count - child process', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-count.json')\n    });\n    runner.setup({\n      use_child_process: true\n    });\n    assert.deepStrictEqual(runner.test_settings.test_workers, {\n      enabled: true,\n      workers: 6\n    });\n\n    return runner.runTests().then(_ => {\n      assert.strictEqual(allArgs.length, 4);\n    });\n  });\n\n  it('test parallel execution with workers count - worker threads', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-count.json')\n    });\n\n    runner.setup({\n      use_child_process: false\n    });\n    assert.deepStrictEqual(runner.test_settings.test_workers, {\n      enabled: true,\n      workers: 6\n    });\n\n    return runner.runTests().then(_ => {\n      assert.strictEqual(taskArgv.length, 4);\n    });\n  });\n\n  it('test parallel execution with workers=count arg', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-count.json'),\n      workers: 2\n    });\n\n    runner.setup();\n    assert.deepStrictEqual(runner.test_settings.test_workers, {\n      enabled: true,\n      workers: 2\n    });\n  });\n\n  it('test parallel execution with workers count and extended envs', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-workers.conf.js'),\n      env: 'chrome'\n    });\n\n    runner.setup();\n\n    assert.deepStrictEqual(runner.test_settings.test_workers, {\n      enabled: true,\n      workers: 5\n    });\n\n    assert.strictEqual(runner.isTestWorkersEnabled(), true);\n  });\n\n  it('test parallel execution with workers disabled per environment', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-disabled.json')\n    });\n\n    runner.setup();\n\n    assert.strictEqual(runner.test_settings.test_workers, false);\n  });\n\n  it('test parallel execution with workers and single source file', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism.json'),\n      _source: [path.join(__dirname, '../../../sampletests/async/test/sample.js')]\n    });\n\n    runner.setup();\n\n    // run in parallel mode even if single source file is provided\n    assert.strictEqual(runner.isConcurrencyEnabled([runner.argv._source]), true);\n  });\n\n  it('test parallel execution with workers and single source folder', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism.json'),\n      _source: path.join(__dirname, '../../../sampletests/before-after')\n    });\n\n    runner.setup();\n\n    assert.strictEqual(runner.isConcurrencyEnabled(), true);\n  });\n\n  it('test parallel execution using selenium server - child process', function() {\n    mockery.registerMock('geckodriver', {\n      path: '/path/to/geckodriver'\n    });\n    mockery.registerMock('chromedriver', {\n      path: '/path/to/chromedriver'\n    });\n    mockery.registerMock('@nightwatch/selenium-server', {\n      path: '/path/to/selenium-server-standalone.3.0.jar'\n    });\n    mockery.registerMock('./service-builders/selenium.js', class SeleniumServer {\n      constructor(settings) {\n        this.settings = settings;\n        this.service = {\n          kill() {\n            return Promise.resolve();\n          }\n        };\n      }\n      async init() {\n        this.initCalled = true;\n      }\n      stop() {\n        this.stopped = true;\n      }\n      setOutputFile(filename) {\n        this.outfilename = filename;\n      }\n    });\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: path.join(__dirname, '../../extra/parallelism-selenium-server.json')\n    });\n    runner.setup({\n      use_child_process: true\n    });\n\n    return runner.runTests().then(_ => {\n      assert.ok(runner.parallelMode());\n      assert.strictEqual(runner.concurrency.globalExitCode, 0);\n      assert.strictEqual(allArgs.length, 4);\n      assert.strictEqual(runner.seleniumService.initCalled, true);\n      assert.strictEqual(runner.seleniumService.stopped, true);\n      assert.strictEqual(runner.seleniumService.outfilename, '');\n      assert.ok(allArgs[0].join(' ').includes('--test-worker --parallel-mode'));\n      assert.ok(allArgs[1].join(' ').includes('--test-worker --parallel-mode'));\n    });\n  });\n\n  it('test parallel execution using selenium server - worker threads', function() {\n    mockery.registerMock('geckodriver', {\n      path: '/path/to/geckodriver'\n    });\n\n    mockery.registerMock('chromedriver', {\n      path: '/path/to/chromedriver'\n    });\n\n    mockery.registerMock('@nightwatch/selenium-server', {\n      path: '/path/to/selenium-server-standalone.3.0.jar'\n    });\n\n    mockery.registerMock('./service-builders/selenium.js', class SeleniumServer {\n      constructor(settings) {\n        this.settings = settings;\n        this.service = {\n          kill() {\n            return Promise.resolve();\n          }\n        };\n      }\n\n      async init() {\n        this.initCalled = true;\n      }\n\n      stop() {\n        this.stopped = true;\n      }\n      setOutputFile(filename) {\n        this.outfilename = filename;\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: path.join(__dirname, '../../extra/parallelism-selenium-server.json')\n    });\n\n    runner.setup({\n      use_child_process: false\n    });\n\n    return runner.runTests().then(_ => {\n      assert.ok(runner.parallelMode());\n      assert.strictEqual(runner.concurrency.globalExitCode, 0);\n      assert.strictEqual(taskArgv.length, 4);\n      assert.strictEqual(runner.seleniumService.initCalled, true);\n      assert.strictEqual(runner.seleniumService.stopped, true);\n      assert.strictEqual(runner.seleniumService.outfilename, '');\n      assert.ok(workerPoolArgv[0].join(' ').includes('--test-worker --parallel-mode'));\n    });\n  });\n\n  it('test concurrency with --headless', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-count.json'),\n      env: 'default',\n      headless: true\n    });\n\n    runner.setup({\n      use_child_process: false\n    });\n    assert.deepStrictEqual(runner.test_settings.test_workers, {\n      enabled: true,\n      workers: 6\n    });\n\n    return runner.runTests().then(_ => {\n      assert.strictEqual(taskArgv[0].env, 'default');\n      assert.strictEqual(taskArgv[0].headless, true);\n    }); \n  });\n\n  it('test Concurrency.getChildProcessArgs with --env=chrome,firefox', function() {\n    const argv = process.argv.slice(0);\n    process.argv = ['node', 'runner.js', '--env=chrome,firefox', '--headless'];\n\n    const Concurrency = common.require('runner/concurrency');\n    const args = Concurrency.getChildProcessArgs();\n\n    process.argv = argv;\n    assert.deepStrictEqual(args, ['--headless']);\n  });\n\n  it('test Concurrency.getChildProcessArgs with --env chrome,firefox', function() {\n    const argv = process.argv.slice(0);\n    process.argv = ['node', 'runner.js', '--env', 'chrome,firefox', '--headless'];\n\n    const Concurrency = common.require('runner/concurrency');\n    const args = Concurrency.getChildProcessArgs();\n\n    process.argv = argv;\n    assert.deepStrictEqual(args, ['--headless']);\n  });\n\n  it('test parallel execution to ensure preservation of all process.execArgv', function() {\n    const argv = process.execArgv;\n    process.execArgv = ['--inspect'];\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-execArgv.json')\n    });\n\n    runner.setup();\n    const worker = runner.concurrency.createChildProcess('test-worker');\n    const args = worker.getArgs();\n\n    process.execArgv = argv;\n    assert.ok(args.includes('--inspect'));\n    assert.ok(args.includes('--parallel-mode'));\n  });\n\n  // TODO: this test is not complete\n  xit('test parallel execution to ensure worker start_process is disabled when using selenium server', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-selenium-server.json')\n    });\n\n    runner.setup();\n    const worker = runner.concurrency.createChildProcess('test-worker');\n\n  });\n\n  it('test random port assignment for parallel execution', function(){\n    const client = Nightwatch.createClient({\n      webdriver: {\n        port: 9999,\n        start_process: true\n      },\n\n      'test_workers': {\n        'enabled': true,\n        'workers': 4\n      }\n    });\n    assert.equal(client.transport.settings.webdriver.port, undefined);\n\n    const client2 = Nightwatch.createClient({\n      webdriver: {\n        port: 9999,\n        start_process: false\n      },\n\n      'test_workers': {\n        'enabled': true,\n        'workers': 4\n      }\n    });\n    assert.equal(client2.transport.settings.webdriver.port, 9999);\n  });\n\n  it('test number of work threads for parallel execution', function() {\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      reporter: 'junit',\n      config: path.join(__dirname, '../../extra/parallelism-count.json'),\n      env: 'default',\n      headless: true\n    });\n\n    runner.setup({});\n\n    return runner.runTests().then(_ => {\n      assert.strictEqual(workerCount, 4);\n    }); \n  });\n});\n"
  },
  {
    "path": "test/src/cli/testParallelExecutionExitCode.js",
    "content": "const util = require('util');\nconst events = require('events');\nconst mockery = require('mockery');\nconst path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\n\ndescribe('test Parallel Execution Exit Code', function() {\n  const allArgs = [];\n  const allOpts = [];\n  this.timeout(5000);\n\n  beforeEach(function() {\n    let index = 0;\n    mockery.enable({useCleanCache: true, warnOnUnregistered: false});\n    mockery.registerMock('package.json', {});\n    mockery.registerMock('child_process', {\n      spawn: function(path, args, opts) {\n        allArgs.push(args);\n        allOpts.push(opts);\n\n        function Stdout() {\n        }\n\n        function Stderr() {\n        }\n\n        util.inherits(Stdout, events.EventEmitter);\n        util.inherits(Stderr, events.EventEmitter);\n\n        let Child = function() {\n          this.stdout = new Stdout();\n          this.stderr = new Stderr();\n          setTimeout(function() {\n            this.emit('close');\n            this.emit('exit', index === 0 ? 1 : 0);\n          }.bind(this), 11);\n        };\n\n        util.inherits(Child, events.EventEmitter);\n\n        return new Child();\n      }\n    });\n    mockery.registerMock('./worker-process.js', class WorkerProcess extends events {\n      constructor(args, settings, maxWorkerCount) {\n        super();\n        this.tasks = [];\n        this.index = 0;\n      }\n\n      addTask({argv}) {\n        this.tasks.push(Promise.reject());\n        Promise.resolve();\n      }\n    });\n\n    const {platform, constants, homedir, release} = require('os');\n    mockery.registerMock('os', {\n      cpus: function() {\n        return [0, 1, 2];\n      },\n      platform, \n      constants,\n      homedir,\n      release\n    });\n  });\n\n  afterEach(function() {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n    allArgs.length = 0;\n    allOpts.length = 0;\n    process.env.__NIGHTWATCH_PARALLEL_MODE = null;\n  });\n\n  it('test parallel execution with code non zero test workers', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    let runner = new CliRunner({\n      config: path.join(__dirname, '../../extra/parallelism-count.json')\n    });\n\n    runner.setup({\n      use_child_process: true\n    });\n\n    let setExitCode = runner.processListener.setExitCode;\n    runner.processListener.setExitCode = function(code) {\n      runner.processListener.setExitCode = setExitCode;\n      assert.strictEqual(code, 1);\n    };\n\n    return runner.runTests();\n  });\n\n  it('test parallel execution with code non zero envs', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    let runner = new CliRunner({\n      config: path.join(__dirname, '../../extra/parallelism-envs.json'),\n      env: 'env1,env2'\n    });\n\n    runner.setup({\n      use_child_process: true\n    });\n\n    let setExitCode = runner.processListener.setExitCode;\n    runner.processListener.setExitCode = function(code) {\n      runner.processListener.setExitCode = setExitCode;\n      assert.strictEqual(code, 1);\n    };\n\n    return runner.runTests();\n  });\n\n  it('test parallel execution with code non zero test workers - worker threads', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    let runner = new CliRunner({\n      config: path.join(__dirname, '../../extra/parallelism-count.json')\n    });\n\n    runner.setup({\n      use_child_process: false\n    });\n\n    let setExitCode = runner.processListener.setExitCode;\n    runner.processListener.setExitCode = function(code) {\n      runner.processListener.setExitCode = setExitCode;\n      assert.strictEqual(code, 1);\n    };\n\n    return runner.runTests();\n  });\n\n  it('test parallel execution with code non zero envs - worker threads', function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    let runner = new CliRunner({\n      config: path.join(__dirname, '../../extra/parallelism-envs.json'),\n      env: 'env1,env2'\n    });\n\n    runner.setup({\n      use_child_proces: true\n    });\n\n    let setExitCode = runner.processListener.setExitCode;\n    runner.processListener.setExitCode = function(code) {\n      runner.processListener.setExitCode = setExitCode;\n      assert.strictEqual(code, 1);\n    };\n\n    return runner.runTests();\n  });\n});\n"
  },
  {
    "path": "test/src/cli/testServiceCreationFromCli.js",
    "content": "const common = require('../../common.js');\nconst mockery = require('mockery');\nconst assert = require('assert');\nconst origPath = require('path');\nconst Options = common.require('transport/selenium-webdriver/options.js');\nconst IS_WINDOWS = process.platform === 'win32';\n\ndescribe('Service creation from cli.js', function() {\n  if (IS_WINDOWS) {\n    return;\n  }\n\n  this.timeout(15000);\n\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnUnregistered: false});\n\n    mockery.registerMock('package.json', {});\n    mockery.registerMock('path', {\n      ...origPath,\n      resolve: function(path, ...args) {\n        if (path === './appium_config.json') {\n          return path;\n        }\n\n        return origPath.resolve(path, ...args);\n      }\n    });\n  });\n\n  afterEach(function() {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n  });\n\n  const fn = function() {};\n  function deleteFromRequireCache(location) {\n    const entry = Object.keys(require.cache).filter(item => {\n      return item.includes(location);\n    });\n\n    entry.forEach(item => {\n      delete require.cache[item];\n    });\n  }\n\n  function mockOptions({onAppiumPathQuery = fn}) {\n    class MockOptions extends Options {\n\n    }\n\n    MockOptions.prototype.getAppiumPath = function () {\n      onAppiumPathQuery();\n\n      return 'path/to/appium';\n    };\n\n    deleteFromRequireCache('selenium-webdriver/options.js');\n\n    mockery.registerMock('./options.js', MockOptions);\n  }\n\n  it('test appium server startup', function() {\n    let appiumPathQueried = false;\n    mockOptions({\n      onAppiumPathQuery() {\n        appiumPathQueried = true;\n      }\n    });\n\n    mockery.registerMock('./appium_config.json', {\n      src_folders: ['test/sampletests/before-after'],\n      output_folder: false,\n      selenium: {\n        start_process: true,\n        use_appium: true\n      },\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false,\n          desiredCapabilities: {\n            browserName: ''\n          }\n        }\n      }\n    });\n  \n    mockery.registerMock('./service-builders/appium.js', class AppiumServer {\n      constructor(settings) {\n        this.settings = settings;\n        this.service = {\n          kill() {\n            return Promise.resolve();\n          }\n        };\n      }\n  \n      async init() {\n        this.initCalled = true;\n      }\n  \n      stop() {\n        this.stopped = true;\n      }\n  \n      setOutputFile(filename) {\n        this.outfilename = filename;\n      }\n    });\n  \n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './appium_config.json'\n    }).setup();\n  \n    return runner.runTests().then(_ => {\n      assert.strictEqual(runner.seleniumService.initCalled, true);\n      assert.strictEqual(runner.seleniumService.stopped, true);\n      assert.strictEqual(runner.seleniumService.outfilename, '');\n      assert.strictEqual(appiumPathQueried, true);\n      assert.strictEqual(runner.seleniumService.settings.webdriver.server_path, 'path/to/appium');\n      assert.strictEqual(runner.seleniumService.settings.selenium['[_started]'], true);\n    });\n  });\n\n  it('test appium server startup with server_path=appium', function() {\n    let appiumPathQueried = false;\n    mockOptions({\n      onAppiumPathQuery() {\n        appiumPathQueried = true;\n      }\n    });\n\n    mockery.registerMock('./appium_config.json', {\n      src_folders: ['test/sampletests/before-after'],\n      output_folder: false,\n      selenium: {\n        start_process: true,\n        use_appium: true,\n        server_path: 'appium'\n      },\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false,\n          desiredCapabilities: {\n            browserName: 'firefox'\n          }\n        }\n      }\n    });\n  \n    mockery.registerMock('./service-builders/appium.js', class AppiumServer {\n      constructor(settings) {\n        this.settings = settings;\n        this.service = {\n          kill() {\n            return Promise.resolve();\n          }\n        };\n      }\n  \n      async init() {\n        this.initCalled = true;\n      }\n  \n      stop() {\n        this.stopped = true;\n      }\n  \n      setOutputFile(filename) {\n        this.outfilename = filename;\n      }\n    });\n  \n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './appium_config.json'\n    }).setup();\n  \n    return runner.runTests().then(_ => {\n      assert.strictEqual(runner.seleniumService.initCalled, true);\n      assert.strictEqual(runner.seleniumService.stopped, true);\n      assert.strictEqual(runner.seleniumService.outfilename, '');\n      assert.strictEqual(appiumPathQueried, false);\n      assert.strictEqual(runner.seleniumService.settings.webdriver.server_path, 'appium');\n      assert.strictEqual(runner.seleniumService.settings.selenium['[_started]'], true);\n    });\n  });\n\n  it('test appium server startup with start_process false', function() {\n    mockery.registerMock('./appium_config.json', {\n      src_folders: ['test/sampletests/before-after'],\n      output_folder: false,\n      selenium: {\n        start_process: false,\n        use_appium: true,\n        host: 'localhost'\n      },\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false,\n          desiredCapabilities: {\n            browserName: ''\n          }\n        }\n      }\n    });\n  \n    let appiumServerStarted = false;\n    mockery.registerMock('./selenium-webdriver/appium.js', class AppiumServer {\n      static createService() {\n        appiumServerStarted = true;\n      }\n    });\n  \n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './appium_config.json'\n    }).setup();\n  \n    return runner.runTests().then(_ => {\n      assert.strictEqual(appiumServerStarted, false);\n      assert.strictEqual(runner.seleniumService, undefined);\n    });\n  });\n\n  it('test selenium server startup if use_appium not used', function() {\n    mockery.registerMock('./appium_config.json', {\n      src_folders: ['test/sampletests/before-after'],\n      output_folder: false,\n      selenium: {\n        start_process: true\n      },\n      test_settings: {\n        'default': {\n          output: false,\n          silent: false,\n          desiredCapabilities: {\n            browserName: 'chrome'\n          }\n        }\n      }\n    });\n  \n    let seleniumServerStarted = false;\n    mockery.registerMock('./selenium-webdriver/selenium.js', class SeleniumServer {\n      static createService() {\n        seleniumServerStarted = true;\n\n        return {\n          async init() {}\n        };\n      }\n    });\n  \n    const CliRunner = common.require('runner/cli/cli.js');\n    const runner = new CliRunner({\n      config: './appium_config.json'\n    }).setup();\n  \n    return runner.runTests().then(_ => {\n      assert.strictEqual(seleniumServerStarted, true);\n      assert.strictEqual(runner.test_settings.selenium['[_started]'], true);\n    });\n  });\n});"
  },
  {
    "path": "test/src/core/testAsyncTree.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst CommandGlobals = require('../../lib/globals/commands-w3c.js');\nconst common = require('../../common.js');\nconst {runTests} = common.require('index.js');\nconst {settings} = common;\n\ndescribe('element().isPresent() command', function() {\n  before(function (done) {\n    CommandGlobals.beforeEach.call(this, done);\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test runner with multiple test interfaces - exports/describe', function () {\n    const srcFolders = [\n      path.join(__dirname, '../../sampletests/withdescribe/basic2')\n    ];\n\n    const globals = {\n      asynctreeFinishedEventCount: 0,\n      queueFinishedEventCount: 0,\n      reporter(results, cb) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n\n        // should equal the number of test cases.\n        assert.equal(globals.asynctreeFinishedEventCount, 3);\n\n        // only counts for the first test case + afterEach\n        assert.equal(globals.queueFinishedEventCount, 2);\n\n        cb();\n      }\n    };\n\n    return runTests(settings({\n      globals,\n      src_folders: srcFolders,\n      output: true,\n      silent: false\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/core/testCreateSession.js",
    "content": "const assert = require('assert');\nconst nock = require('nock');\nconst path = require('path');\nconst Nocks = require('../../lib/nocks.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test Request With Credentials', function () {\n  beforeEach(function () {\n    Nocks.cleanAll();\n    try {\n      Nocks.enable();\n    } catch (e) {\n    }\n\n  });\n\n  afterEach(function () {\n    Nocks.deleteSession();\n  });\n\n  after(function () {\n    Nocks.disable();\n  });\n\n  it('Test create session in Firefox', async function () {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'firefox',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    const client = Nightwatch.createClient({\n      selenium_port: 10195,\n      silent: false,\n      output: false\n    });\n\n    const result = await client.createSession();\n    assert.deepStrictEqual(client.transport.desiredCapabilities, {\n      browserName: 'firefox'\n    });\n    assert.deepStrictEqual(result, {\n      sessionId: '1352110219202',\n      host: 'localhost',\n      port: 10195,\n      capabilities: {browserName: 'firefox', version: 'TEST', platform: 'TEST'}\n    });\n  });\n\n  it('Test create session in Chrome', async function () {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'chrome',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    const client = Nightwatch.createClient({\n      selenium_port: 10195,\n      silent: false,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    });\n\n    const result = await client.createSession();\n    assert.deepStrictEqual(client.transport.desiredCapabilities, {\n      browserName: 'chrome'\n    });\n    assert.deepStrictEqual(result, {\n      sessionId: '1352110219202',\n      host: 'localhost',\n      port: 10195,\n      capabilities: {\n        browserName: 'chrome', version: 'TEST', platform: 'TEST'\n      }\n    });\n  });\n\n  it('Test create session in Edge', async function () {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'MicrosoftEdge',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    const client = Nightwatch.createClient({\n      selenium_port: 10195,\n      silent: false,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'MicrosoftEdge'\n      }\n    });\n\n    const result = await client.createSession();\n    assert.deepStrictEqual(client.transport.desiredCapabilities, {\n      browserName: 'MicrosoftEdge'\n    });\n    assert.deepStrictEqual(result, {\n      sessionId: '1352110219202',\n      host: 'localhost',\n      port: 10195,\n      capabilities: {\n        browserName: 'MicrosoftEdge', version: 'TEST', platform: 'TEST'\n      }\n    });\n  });\n\n  it('Test create session with headless mode in Firefox', async function () {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'firefox',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    const client = Nightwatch.createClient({\n      selenium_port: 10195,\n      silent: false,\n      output: false\n    });\n\n    let sessionOptions;\n    const driverFn = client.transport.createDriver;\n    client.transport.createDriver = function({options}) {\n      sessionOptions = options;\n\n      return driverFn.call(client.transport, {options});\n    };\n\n    const session = await client.createSession({\n      argv: {\n        headless: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1352110219202',\n      host: 'localhost',\n      port: 10195,\n      capabilities: {browserName: 'firefox', version: 'TEST', platform: 'TEST'}\n    });\n    assert.deepStrictEqual(sessionOptions.get('moz:firefoxOptions'), {\n      args: ['-headless'],\n      prefs: {\n        'remote.active-protocols': 3\n      }\n    });\n  });\n\n  it('Test create session with headless mode in Chrome', async function () {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'chrome',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    const client = Nightwatch.createClient({\n      selenium_port: 10195,\n      silent: false,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    });\n\n    let sessionOptions;\n    const driverFn = client.transport.createDriver;\n    client.transport.createDriver = function({options}) {\n      sessionOptions = options;\n\n      return driverFn.call(client.transport, {options});\n    };\n\n    const session = await client.createSession({\n      argv: {\n        headless: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1352110219202',\n      host: 'localhost',\n      port: 10195,\n      capabilities: {browserName: 'chrome', version: 'TEST', platform: 'TEST'}\n    });\n    assert.deepStrictEqual(sessionOptions.get('goog:chromeOptions'), {args: ['headless=new']});\n  });\n\n  it('Test create session with headless mode in Edge', async function () {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'MicrosoftEdge',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    const client = Nightwatch.createClient({\n      selenium_port: 10195,\n      silent: false,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'MicrosoftEdge'\n      }\n    });\n\n    let sessionOptions;\n    const driverFn = client.transport.createDriver;\n    client.transport.createDriver = function({options}) {\n      sessionOptions = options;\n\n      return driverFn.call(client.transport, {options});\n    };\n\n    const session = await client.createSession({\n      argv: {\n        headless: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1352110219202',\n      host: 'localhost',\n      port: 10195,\n      capabilities: {browserName: 'MicrosoftEdge', version: 'TEST', platform: 'TEST'}\n    });\n\n    assert.deepStrictEqual(sessionOptions.get('ms:edgeOptions'), {args: ['headless=new']});\n  });\n\n  it('Test create session with headless mode in Chrome with existing args', async function () {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'chrome',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    const client = Nightwatch.createClient({\n      selenium_port: 10195,\n      silent: false,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {\n          args: ['--no-sandbox']\n        }\n      }\n    });\n\n    let sessionOptions;\n    const driverFn = client.transport.createDriver;\n    client.transport.createDriver = function({options}) {\n      sessionOptions = options;\n\n      return driverFn.call(client.transport, {options});\n    };\n\n    const session = await client.createSession({\n      argv: {\n        headless: true\n      }\n    });\n\n    assert.deepStrictEqual(sessionOptions.get('goog:chromeOptions'), {\n      args: [\n        '--no-sandbox',\n        'headless=new'\n      ]\n    });\n  });\n\n  it('Test create session with headless mode in Edge with existing args', async function () {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'MicrosoftEdge',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    const client = Nightwatch.createClient({\n      selenium_port: 10195,\n      silent: false,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'MicrosoftEdge',\n        'ms:edgeOptions': {\n          args: ['--no-sandbox']\n        }\n      }\n    });\n\n    let sessionOptions;\n    const driverFn = client.transport.createDriver;\n    client.transport.createDriver = function({options}) {\n      sessionOptions = options;\n\n      return driverFn.call(client.transport, {options});\n    };\n\n    const session = await client.createSession({\n      argv: {\n        headless: true\n      }\n    });\n\n    assert.deepStrictEqual(sessionOptions.get('ms:edgeOptions'), {\n      args: [\n        '--no-sandbox',\n        'headless=new'\n      ]\n    });\n  });\n\n  it('Test blank object capabilities', async function () {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'chrome',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    const client = Nightwatch.createClient({\n      selenium_port: 10195,\n      silent: false,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      capabilities: {}\n    });\n\n    const result = await client.createSession();\n    assert.deepStrictEqual(client.transport.desiredCapabilities, {\n      browserName: 'chrome'\n    });\n    assert.deepStrictEqual(result, {\n      sessionId: '1352110219202',\n      host: 'localhost',\n      port: 10195,\n      capabilities: {\n        browserName: 'chrome', version: 'TEST', platform: 'TEST'\n      }\n    });\n  });\n\n  it('Test blank browserName', async function () {\n    assert.throws(function() {\n      const client = Nightwatch.createClient({\n        selenium_port: 10195,\n        silent: false,\n        output: false,\n        desiredCapabilities: {},\n        capabilities: {\n          alwaysMatch: {}\n        }\n      });\n    }, /Error: Unknown browser:/);\n  });\n\n  it('Test create session with browsername null - Appium support', async function () {\n    nock('http://localhost:4723')\n      .post('/wd/hub/session')\n      .reply(201, {\n        value: {\n          capabilities: {\n            platformName: 'iOS',\n            platformVersion: '15.5',\n            deviceName: 'iPhone 13',\n            name: 'sample test goes here'\n          },\n          sessionId: '1352110219202'\n        }\n      });\n\n    const client = Nightwatch.createClient({\n      webdriver: {\n        start_process: false\n      },\n      selenium: {\n        start_process: false,\n        host: 'localhost',\n        port: '4723'\n      },\n      desiredCapabilities: {\n        browserName: null,\n        platformName: 'iOS',\n        platformVersion: '15.5',\n        deviceName: 'iPhone 13'\n      }\n    });\n\n    const result = await client.createSession();\n    assert.deepStrictEqual(result, {\n      capabilities: {\n        platformName: 'iOS',\n        platformVersion: '15.5',\n        deviceName: 'iPhone 13',\n        name: 'sample test goes here'\n      },\n      sessionId: '1352110219202',\n      host: 'localhost',\n      port: '4723'\n    });\n  });\n\n  it('Test create session with use_appium property and random browser - Appium support', async function () {\n    nock('http://somewhere:9999')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        assert.deepEqual(requestBody, {\n          capabilities: {\n            firstMatch: [{}],\n            alwaysMatch: {\n              browserName: 'acmeBrowser',\n              platformName: 'android',\n              'appium:platformVersion': '12.0'\n            }\n          }\n        });\n\n        return {\n          value: {\n            capabilities: {\n              browserName: 'acmeBrowser',\n              platformName: 'android',\n              platformVersion: '12.0',\n              name: 'sample test goes here'\n            },\n            sessionId: '1352110219202'\n          }\n        };\n      });\n\n    const client = Nightwatch.createClient({\n      webdriver: {\n        start_process: false\n      },\n      selenium: {\n        start_process: false,\n        use_appium: true,\n        host: 'somewhere',\n        port: 9999\n      },\n      desiredCapabilities: {\n        browserName: 'acmeBrowser',\n        platformName: 'android',\n        'appium:platformVersion': '12.0'\n      }\n    });\n\n    const result = await client.createSession();\n    assert.deepStrictEqual(result, {\n      capabilities: {\n        browserName: 'acmeBrowser',\n        platformName: 'android',\n        platformVersion: '12.0',\n        name: 'sample test goes here'\n      },\n      sessionId: '1352110219202',\n      host: 'somewhere',\n      port: 9999\n    });\n  });\n\n  it('Test create session with browserstack', async function () {\n    nock('https://hub.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n\n        assert.deepEqual(requestBody, {\n          capabilities: {\n            firstMatch: [{}],\n            alwaysMatch: {\n              browserName: 'chrome',\n              'bstack:options': {\n                local: 'false',\n                sessionName: 'Try 1',\n                userName: 'test_user',\n                accessKey: 'test_key',\n                os: 'OS X',\n                osVersion: 'Monterey',\n                buildName: 'Nightwatch Programmatic Api Demo'\n              },\n              'goog:chromeOptions': {\n                w3c: false\n              }\n            }\n          }\n        });\n\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=0')\n      .times(2)\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'WIN_CHROME_PROD_SANITY_LIVE_1831',\n            duration: 47,\n            status: 'running',\n            hashed_id: '8dd73aad3365429dec0ec12cf64c0c475a22dasds',\n            build_tag: null\n          }\n        },\n        {\n          automation_build: {\n            name: 'External monitoring - aps - 2022-08-30',\n            duration: 44,\n            status: 'done',\n            hashed_id: '8dd73aad3365429dec0ec12cf64c0c475a22dasdk',\n            build_tag: null\n          }\n        }\n      ]);\n\n    const client = Nightwatch.createClient({\n      webdriver: {\n        start_process: false\n      },\n      selenium: {\n        host: 'hub.browserstack.com',\n        port: 443\n      },\n      desiredCapabilities: {\n        'bstack:options': {\n          local: 'false',\n          userName: 'test_user',\n          accessKey: 'test_key',\n          os: 'OS X',\n          osVersion: 'Monterey'\n        },\n        browserName: 'chrome',\n        chromeOptions: {\n          w3c: false\n        }\n      },\n\n      parallel: false\n    });\n\n    client.mergeCapabilities({\n      name: 'Try 1',\n      build: 'Nightwatch Programmatic Api Demo'\n    });\n\n    const result = await client.createSession();\n    assert.deepEqual(result, {\n      sessionId: '1352110219202',\n      host: 'hub.browserstack.com',\n      port: 443,\n      capabilities: {\n        firstMatch: [{}],\n        alwaysMatch: {\n          browserName: 'chrome',\n          'bstack:options': {\n            local: 'false',\n            sessionName: 'Try 1',\n            userName: 'test_user',\n            accessKey: 'test_key',\n            os: 'OS X',\n            osVersion: 'Monterey',\n            buildName: 'Nightwatch Programmatic Api Demo'\n          },\n          'goog:chromeOptions': {\n            w3c: false\n          }\n        }\n      }\n    });\n\n    const buildId = await client.transport.getBuildId();\n    assert.strictEqual(buildId, undefined);\n\n    assert.strictEqual(client.api.isAppiumClient(), false);\n  });\n\n  it('Test create session with browserstack and browserName set to null (App Automate)', async function () {\n    nock('https://hub.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n\n        assert.deepEqual(requestBody, {\n          capabilities: {\n            firstMatch: [{}],\n            alwaysMatch: {\n              'appium:app': 'bs://878bdf21505f0004ce',\n              'bstack:options': {\n                local: 'false',\n                sessionName: 'Try 1',\n                userName: 'test_user',\n                accessKey: 'test_key',\n                osVersion: '14',\n                deviceName: 'iPhone 12',\n                realMobile: 'true',\n                buildName: 'Nightwatch Programmatic Api Demo'\n              }\n            }\n          }\n        });\n\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: {\n              platform: 'MAC',\n              platformName: 'iOS',\n              deviceName: 'iPhone 12',\n              realMobile: true\n            }\n          }\n        };\n      });\n\n    nock('https://api-cloud.browserstack.com')\n      .post('/app-automate/upload')\n      .reply(200, {\n        app_url: 'bs://878bdf21505f0004ce'\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/app-automate/builds.json?status=running&limit=20&offset=0')\n      .times(2)\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'WIN_CHROME_PROD_SANITY_LIVE_1831',\n            duration: 47,\n            status: 'running',\n            hashed_id: '8dd73aad3365429dec0ec12cf64c0c475a22dasds',\n            build_tag: null\n          }\n        },\n        {\n          automation_build: {\n            name: 'External monitoring - aps - 2022-08-30',\n            duration: 44,\n            status: 'done',\n            hashed_id: '8dd73aad3365429dec0ec12cf64c0c475a22dasdk',\n            build_tag: null\n          }\n        }\n      ]);\n\n    const client = Nightwatch.createClient({\n      webdriver: {\n        start_process: false\n      },\n      selenium: {\n        host: 'hub.browserstack.com',\n        port: 443\n      },\n      desiredCapabilities: {\n        'bstack:options': {\n          local: 'false',\n          userName: 'test_user',\n          accessKey: 'test_key',\n          osVersion: '14',\n          deviceName: 'iPhone 12',\n          realMobile: 'true'\n        },\n        browserName: null,\n        chromeOptions: {\n          w3c: false\n        },\n        appUploadUrl: 'https://some_host.com/app.apk'\n      },\n\n      parallel: false\n    });\n\n    client.mergeCapabilities({\n      name: 'Try 1',\n      build: 'Nightwatch Programmatic Api Demo'\n    });\n\n    const result = await client.createSession();\n    assert.deepStrictEqual(result, {\n      sessionId: '1352110219202',\n      host: 'hub.browserstack.com',\n      port: 443,\n      capabilities: {\n        platform: 'MAC',\n        platformName: 'iOS',\n        deviceName: 'iPhone 12',\n        realMobile: true\n      }\n    });\n\n    const buildId = await client.transport.getBuildId();\n    assert.strictEqual(buildId, undefined);\n\n    assert.strictEqual(client.transport.uploadedAppUrl, 'bs://878bdf21505f0004ce');\n\n    assert.strictEqual(client.settings.selenium.use_appium, undefined);\n    assert.strictEqual(client.api.isAppiumClient(), true);\n  });\n\n  it('Test create session with Browserstack App Automate using custom id', async function () {\n    nock('https://hub.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        assert.deepEqual(requestBody, {\n          capabilities: {\n            firstMatch: [{}],\n            alwaysMatch: {\n              'appium:automationName': 'UiAutomator2',\n              'appium:platformVersion': '9.0',\n              'appium:deviceName': 'Google Pixel 3',\n              'appium:app': 'sample_app',\n              'browserName': '',\n              'bstack:options': {\n                local: 'false',\n                sessionName: 'Try 1',\n                userName: 'test_user',\n                accessKey: 'test_key',\n                realMobile: true,\n                buildName: 'Nightwatch Programmatic Api Demo'\n              }\n            }\n          }\n        });\n\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: {\n              platform: 'LINUX',\n              platformName: 'Android',\n              deviceName: '8B3X12Y71',\n              automationName: 'uiautomator2',\n              platformVersion: '9',\n              realMobile: true\n            }\n          }\n        };\n      });\n\n    nock('https://api-cloud.browserstack.com')\n      .post('/app-automate/upload')\n      .reply(200, function (uri, requestBody) {\n        const body = requestBody.toString();\n        assert.strictEqual(body.includes('name=\"custom_id\"'), true);\n        assert.strictEqual(body.includes('sample_app'), true);\n        assert.strictEqual(body.includes('name=\"file\"; filename=\"nightwatch.json\"'), true);\n\n        return {\n          app_url: 'bs://878bdf21505f0004ce',\n          custom_id: 'sample_app',\n          shareable_id: 'test_user/sample_app'\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/app-automate/builds.json?status=running&limit=20&offset=0')\n      .times(2)\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'Nightwatch Programmatic Api Demo',\n            status: 'running',\n            hashed_id: '123456789'\n          }\n        },\n        {\n          automation_build: {\n            name: 'WIN_CHROME_PROD_SANITY_LIVE_1831',\n            duration: 47,\n            status: 'running',\n            hashed_id: '8dd73aad3365429dec0ec12cf64c0c475a22dasds',\n            build_tag: null\n          }\n        },\n        {\n          automation_build: {\n            name: 'External monitoring - aps - 2022-08-30',\n            duration: 44,\n            status: 'done',\n            hashed_id: '8dd73aad3365429dec0ec12cf64c0c475a22dasdk',\n            build_tag: null\n          }\n        }\n      ]);\n\n    const client = Nightwatch.createClient({\n      webdriver: {\n        start_process: false\n      },\n      selenium: {\n        host: 'hub.browserstack.com',\n        port: 443\n      },\n      desiredCapabilities: {\n        'bstack:options': {\n          local: 'false',\n          userName: 'test_user',\n          accessKey: 'test_key',\n          realMobile: true\n        },\n        'appium:options': {\n          automationName: 'UiAutomator2',\n          app: 'sample_app',\n          deviceName: 'Google Pixel 3',\n          platformVersion: '9.0'\n        },\n        browserName: '',\n        appUploadPath: path.resolve(__dirname, '../../extra/nightwatch.json')\n      },\n      parallel: false\n    });\n\n    client.mergeCapabilities({\n      name: 'Try 1',\n      build: 'Nightwatch Programmatic Api Demo'\n    });\n\n    const result = await client.createSession();\n    assert.deepStrictEqual(result, {\n      sessionId: '1352110219202',\n      host: 'hub.browserstack.com',\n      port: 443,\n      capabilities: {\n        platform: 'LINUX',\n        platformName: 'Android',\n        deviceName: '8B3X12Y71',\n        automationName: 'uiautomator2',\n        platformVersion: '9',\n        realMobile: true\n      }\n    });\n\n    const buildId = await client.transport.getBuildId();\n    assert.strictEqual(buildId, '123456789');\n\n    assert.strictEqual(client.transport.uploadedAppUrl, undefined);\n\n    assert.strictEqual(client.settings.selenium.use_appium, undefined);\n    assert.strictEqual(client.api.isAppiumClient(), true);\n  });\n\n  it('Test create session with browserstack and when buildName is not set', async function () {\n    nock('http://hub.browserstack.com:4444')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n\n        assert.deepEqual(requestBody, {\n          capabilities: {\n            firstMatch: [{}],\n            alwaysMatch: {\n              browserName: 'firefox',\n              'moz:firefoxOptions': {\n                prefs: {\n                  'remote.active-protocols': 3\n                }\n              },\n              'bstack:options': {\n                local: 'false',\n                userName: 'test_user',\n                accessKey: 'test_key',\n                os: 'OS X',\n                osVersion: 'Monterey',\n                buildName: 'nightwatch-test-build'\n              }\n            }\n          }\n        });\n\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=0')\n      .times(2)\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'nightwatch-test-build',\n            status: 'running',\n            hashed_id: '123-456-789'\n          }\n        },\n        {\n          automation_build: {\n            name: 'WIN_CHROME_PROD_SANITY_LIVE_1831',\n            duration: 47,\n            status: 'running',\n            hashed_id: '8dd73aad3365429dec0ec12cf64c0c475a22dasds',\n            build_tag: null\n          }\n        },\n        {\n          automation_build: {\n            name: 'External monitoring - aps - 2022-08-30',\n            duration: 44,\n            status: 'done',\n            hashed_id: '8dd73aad3365429dec0ec12cf64c0c475a22dasdk',\n            build_tag: null\n          }\n        }\n      ]);\n\n    const client = Nightwatch.createClient({\n      webdriver: {\n        start_process: false\n      },\n      selenium: {\n        host: 'hub.browserstack.com',\n        port: 4444\n      },\n      desiredCapabilities: {\n        'bstack:options': {\n          local: 'false',\n          userName: 'test_user',\n          accessKey: 'test_key',\n          os: 'OS X',\n          osVersion: 'Monterey'\n        },\n        chromeOptions: {\n          w3c: false\n        }\n      },\n\n      parallel: false\n    });\n\n    const result = await client.createSession();\n    assert.deepStrictEqual(result, {\n      sessionId: '1352110219202',\n      host: 'hub.browserstack.com',\n      port: 4444,\n      capabilities: {\n        firstMatch: [{}],\n        alwaysMatch: {\n          browserName: 'firefox',\n          'moz:firefoxOptions': {\n            prefs: {\n              'remote.active-protocols': 3\n            }\n          },\n          'bstack:options': {\n            local: 'false',\n            userName: 'test_user',\n            accessKey: 'test_key',\n            os: 'OS X',\n            osVersion: 'Monterey',\n            buildName: 'nightwatch-test-build'\n          }\n        }\n      }\n    });\n\n    const buildId = await client.transport.getBuildId();\n    assert.strictEqual(buildId, '123-456-789');\n  });\n\n  it('Test create session with browserstack with random browser and update buildName', async function () {\n    nock('https://hub.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        assert.deepEqual(requestBody, {\n          capabilities: {\n            firstMatch: [{}],\n            alwaysMatch: {\n              browserName: 'acmeBrowser',\n              'bstack:options': {\n                local: 'false',\n                sessionName: 'Try 1',\n                userName: 'test_user',\n                accessKey: 'test_key',\n                os: 'OS X',\n                osVersion: 'Monterey',\n                buildName: 'Nightwatch Programmatic Api Demo'\n              }\n            }\n          }\n        });\n\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=0')\n      .times(2)\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'Nightwatch Programmatic Api Demo',\n            status: 'running',\n            hashed_id: '123456789'\n          }\n        },\n        {\n          automation_build: {\n            name: 'WIN_CHROME_PROD_SANITY_LIVE_1831',\n            duration: 47,\n            status: 'running',\n            hashed_id: '8dd73aad3365429dec0ec12cf64c0c475a22dasds',\n            build_tag: null\n          }\n        },\n        {\n          automation_build: {\n            name: 'External monitoring - aps - 2022-08-30',\n            duration: 44,\n            status: 'done',\n            hashed_id: '8dd73aad3365429dec0ec12cf64c0c475a22dasdk',\n            build_tag: null\n          }\n        }\n      ]);\n\n    const client = Nightwatch.createClient({\n      webdriver: {\n        start_process: false\n      },\n      selenium: {\n        host: 'hub.browserstack.com',\n        port: 443\n      },\n      desiredCapabilities: {\n        'bstack:options': {\n          local: 'false',\n          userName: 'test_user',\n          accessKey: 'test_key',\n          os: 'OS X',\n          osVersion: 'Monterey'\n        },\n        browserName: 'acmeBrowser'\n      },\n      parallel: false\n    });\n\n    client.mergeCapabilities({\n      name: 'Try 1',\n      buildName: 'Nightwatch Programmatic Api Demo'\n    });\n\n    const result = await client.createSession();\n    assert.deepStrictEqual(result, {\n      sessionId: '1352110219202',\n      host: 'hub.browserstack.com',\n      port: 443,\n      capabilities: {\n        firstMatch: [{}],\n        alwaysMatch: {\n          browserName: 'acmeBrowser',\n          'bstack:options': {\n            local: 'false',\n            sessionName: 'Try 1',\n            userName: 'test_user',\n            accessKey: 'test_key',\n            os: 'OS X',\n            osVersion: 'Monterey',\n            buildName: 'Nightwatch Programmatic Api Demo'\n          }\n        }\n      }\n    });\n\n    const buildId = await client.transport.getBuildId();\n    assert.strictEqual(buildId, '123456789');\n  });\n});\n"
  },
  {
    "path": "test/src/core/testPageObjectApi.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst Nocks = require('../../lib/nocks.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test PageObjectApi', function () {\n  beforeEach(function (done) {\n    Nocks.enable().cleanAll().createSession();\n    Nightwatch.init({\n      page_objects_path: path.join(__dirname, '../../extra/pageobjects/pages'),\n      plugins: [path.join(__dirname, '../../extra/plugin')]\n    }, function () {\n      done();\n    });\n    this.client = Nightwatch.client();\n    //this.client.initialize().then(() => done());\n  });\n\n  afterEach(function () {\n    Nocks.deleteSession().disable();\n  });\n\n  it('testPageObjectProperties', function () {\n    const page = this.client.api.page.simplePageObj();\n    assert.ok('elements' in page);\n    assert.ok('name' in page);\n    assert.ok('section' in page);\n    assert.ok('url' in page);\n    assert.ok('api' in page);\n    assert.ok('client' in page);\n    assert.ok('testCommand' in page);\n\n    assert.strictEqual(typeof page.api, 'object');\n    assert.strictEqual(typeof page.client, 'object');\n    assert.strictEqual(typeof page.elements, 'object');\n    assert.strictEqual(page.name, 'simplePageObj');\n    assert.strictEqual(page.url, 'http://localhost.com');\n    assert.strictEqual(page.testCommand(), page);\n\n    assert.ok('loginCss' in page.elements);\n    assert.ok('loginXpath' in page.elements);\n    assert.ok('signUp' in page.section);\n\n    assert.ok('help' in page.section.signUp.elements);\n    assert.ok('getStarted' in page.section.signUp.section);\n\n    const elements = page.elements;\n    assert.strictEqual(elements.loginCss.selector, '#weblogin');\n    assert.strictEqual(elements.loginCss.locateStrategy, 'css selector');\n    assert.strictEqual(elements.loginXpath.selector, '//weblogin');\n    assert.strictEqual(elements.loginXpath.locateStrategy, 'xpath');\n    assert.strictEqual(elements.loginAsString.selector, '#weblogin');\n    assert.strictEqual(elements.loginAsString.locateStrategy, 'css selector');\n  });\n\n  it('testPageObjectElementsArray', function () {\n    const page = this.client.api.page.pageObjElementsArray();\n    assert.ok('elements' in page);\n\n    assert.ok('someElement' in page.elements);\n    assert.ok('otherElement' in page.elements);\n    assert.strictEqual(page.elements.someElement.selector, '#element');\n    assert.strictEqual(page.elements.otherElement.selector, '#otherElement');\n  });\n\n  it('testPageObjectSubDirectory', function () {\n    assert.ok('addl' in this.client.api.page);\n    assert.ok('simplePageObject' in this.client.api.page.addl);\n  });\n\n  it('testPageObjectAssertionsLoaded', function () {\n    const page = this.client.api.page.simplePageObj();\n\n    assert.ok('assert' in page);\n    assert.ok('verify' in page);\n    assert.ok('expect' in page);\n    assert.ok('title' in page.assert);\n    assert.ok('title' in page.verify);\n    assert.ok('containsText' in page.assert);\n    assert.ok('containsText' in page.verify);\n    assert.ok('ok' in page.assert);\n    assert.ok('ok' in page.verify);\n    assert.ok('element' in page.expect);\n    assert.ok('section' in page.expect);\n    assert.strictEqual(typeof page.assert.containsText, 'function');\n    assert.strictEqual(typeof page.verify.containsText, 'function');\n    assert.strictEqual(typeof page.assert.title, 'function');\n    assert.strictEqual(typeof page.verify.title, 'function');\n    assert.strictEqual(typeof page.expect.element('@loginCss'), 'object');\n    assert.strictEqual(typeof page.expect.section('signUp'), 'object');\n  });\n\n  it('testPageObjectCommandsLoaded', function () {\n    const page = this.client.api.page.simplePageObj();\n\n    assert.ok('click' in page);\n    assert.ok('waitForElementPresent' in page);\n    assert.ok('end' in page);\n    assert.ok(!('switchToWindow' in page));\n  });\n\n  it('testPageObjectPluginLoaded', function() {\n\n    const page = this.client.api.page.simplePageObj();\n\n    assert.ok('customCommand' in page);\n    assert.ok('customAssertion' in page.assert);\n    assert.strictEqual(typeof page.customCommand, 'function');\n    assert.strictEqual(typeof page.assert.customAssertion, 'function');\n  });\n});\n\n"
  },
  {
    "path": "test/src/core/testPageObjectCommands.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst MockServer = require('../../lib/mockserver.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test PageObject Commands', function () {\n  before(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', function () {\n      done();\n    });\n  });\n\n  after(function (done) {\n    this.server.close(function () {\n      done();\n    });\n  });\n\n  beforeEach(function (done) {\n    Nightwatch.init({\n      page_objects_path: path.join(__dirname, '../../extra/pageobjects/pages')\n    }, function () {\n      done();\n    });\n\n    this.client = Nightwatch.client();\n  });\n\n  it('testPageObjectElementCommandWithMutliArgs', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/value',\n      method: 'POST',\n      postdata: '{\"text\":\"1\", \"value\":[\"1\"]}',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0\n      })\n    }, true);\n\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/element/0/clear',\n      postdata: {},\n      'response': {\n        sessionId: '1352110219202',\n        status: 0\n      }\n    });\n\n    const page = this.client.api.page.simplePageObj();\n    page.setValue('@loginCss', '1', function callback(result) {\n      assert.strictEqual(result.status, 0);\n      done();\n    });\n\n    this.client.start();\n  });\n\n  it('testPageObjectCallbackContext', function (done) {\n    const api = this.client.api;\n    const page = api.page.simplePageObj();\n\n    page\n      .waitForElementPresent('#weblogin', 1000, true, function callback(result) {\n        assert.strictEqual(this, api, 'page callback context using selector should equal api');\n      })\n      .waitForElementPresent('#weblogin', 1000, true, function callback(result) {\n        assert.strictEqual(this, api, 'page callback context using selector with message should equal api');\n      }, 'Test sample message')\n      .waitForElementPresent('@loginCss', 1000, true, function callback(result) {\n        assert.strictEqual(this, api, 'page callback context using element should equal api');\n      })\n      .waitForElementPresent('@loginCss', 1000, true, function callback(result) {\n        assert.strictEqual(this, api, 'page callback context using element with message should equal api');\n        done();\n      }, 'Test sample message');\n\n    this.client.start();\n  });\n\n  it('testPageObjectLocateStrategy', function (done) {\n    const client = this.client;\n    const page = client.api.page.simplePageObj();\n\n    assert.strictEqual(client.locateStrategy, 'css selector', 'locateStrategy should default to css selector');\n\n    page\n      .waitForElementPresent('@loginXpath', 1000, true, function callback(result) {\n        assert.ok(result.value, 'Element was not found.');\n        assert.strictEqual(client.locateStrategy, 'css selector', 'locateStrategy should restore to previous css selector in callback when using xpath element');\n\n        done();\n      });\n\n    this.client.start(function (err) {\n      if (err) {\n        done(err);\n      }\n    });\n  });\n\n  it('testPageObjectElementRecursion', function (done) {\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/element/1/click',\n      'response': JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0\n      })\n    }, true);\n    const client = this.client;\n    const section = client.api.page.simplePageObj().section.signUp;\n    section.click('@help', function callback(result) {\n      assert.strictEqual(result.status, 0, result.value && result.value.message || 'An error occurred:\\n' + JSON.stringify(result));\n    });\n\n    client.api.perform(function () {\n      assert.strictEqual(client.locateStrategy, 'css selector');\n    });\n    this.client.start(err => done(err));\n  });\n\n  it('testPageObjectPluralElementRecursion', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/1/elements',\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: [{ELEMENT: '1'}]\n      })\n    });\n\n    const section = this.client.api.page.simplePageObj().section.signUp;\n    section.waitForElementPresent('@help', 1000, true, function callback(result) {\n      assert.strictEqual(result.status, 0);\n      assert.strictEqual(result.value.length, 1);\n      assert.deepStrictEqual(result.value[0], {ELEMENT: '1'});\n      assert.strictEqual(result.WebdriverElementId, '1');\n    });\n\n    this.client.start(function (err) {\n      done(err);\n    });\n  });\n\n  it('testPageObjectElementCommandSwitchLocateStrategy', function (done) {\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/element/0/click',\n      'response': JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0\n      })\n    }, true);\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/element/0/click',\n      'response': JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0\n      })\n    }, true);\n\n    const page = this.client.api.page.simplePageObj();\n\n    page.click('@loginCss', function callback(result) {\n      assert.strictEqual(result.status, 0);\n    }).click('@loginXpath', function callback(result) {\n      assert.strictEqual(result.status, 0);\n      done();\n    });\n\n    this.client.start();\n  });\n\n  it('testPageObjectInvalidElementCommand', function (done) {\n    const page = this.client.api.page.simplePageObj();\n\n    assert.throws(\n      function () {\n        page.click('@invalidElement');\n      },\n      {\n        name: 'Error',\n        message: 'Element \"invalidElement\" was not found in \"simplePageObj\". Available elements: loginAsString, loginCss, loginIndexed, loginXpath, loginId'\n      }\n    );\n    done();\n  });\n\n  it('testAsyncPageObjectInvalidElementCommand', function (done) {\n    const page = this.client.api.page.simplePageObj();\n\n    assert.rejects(\n      async function () {\n        page.click('@invalidElement');\n      }, 'Element command on an invalid element should throw exception'\n    );\n    done();\n  });\n\n  it('testPageObjectPropsFunctionReturnsObject', function () {\n    const page = this.client.api.page.simplePageObj();\n\n    assert.strictEqual(typeof page.props, 'object', 'props function should be called and set page.props equals its returned object');\n    assert.strictEqual(page.props.url, page.url, 'props function should be called with page context');\n  });\n\n  it('testSectionObjectPropsFunctionReturnsObject', function () {\n    const page = this.client.api.page.simplePageObj();\n\n    assert.strictEqual(typeof page.section.propTest.props, 'object', 'props function should be called and set page.props equals its returned object');\n    assert.ok(page.section.propTest.props.defaults.propTest, 'props function should be called with page context');\n    assert.strictEqual(page.section.propTest.props.defaults.propTest, '#propTest Value');\n  });\n\n  it('testPageObjectWithUrlChanged', function (done) {\n    const page = this.client.api.page.simplePageObj();\n    const urlsArr = [];\n    page.api.url = function (url) {\n      urlsArr.push(url);\n    };\n\n    page.navigate();\n\n    page.api.perform(function () {\n      page.url = function () {\n        return 'http://nightwatchjs.org';\n      };\n    });\n\n    page.api.perform(function () {\n      page.navigate();\n    });\n\n    page.api.perform(function () {\n      try {\n        assert.deepStrictEqual(urlsArr, ['http://localhost.com', 'http://nightwatchjs.org']);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n\n    this.client.start();\n  });\n\n  it('testPageObject navigate() with url param', function (done) {\n    const page = this.client.api.page.simplePageObj();\n    const urlsArr = [];\n    page.api.url = function (url) {\n      urlsArr.push(url);\n    };\n\n    page.navigate('http://local');\n\n    page.api.perform(function () {\n      page.url = function () {\n        return 'http://nightwatchjs.org';\n      };\n    });\n\n    page.api.perform(function () {\n      page.navigate();\n    });\n\n    page.api.perform(function () {\n      try {\n        assert.deepStrictEqual(urlsArr, ['http://local', 'http://nightwatchjs.org']);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n\n    this.client.start();\n  });\n\n  it('testPageObject navigate() with url param and callback', function (done) {\n    const page = this.client.api.page.simplePageObj();\n    const urlsArr = [];\n    page.api.url = function (url, callback) {\n      urlsArr.push(url);\n      callback();\n    };\n    let called = false;\n    page.navigate('http://local', function () {\n      called = true;\n    });\n\n    page.api.perform(function () {\n      try {\n        assert.strictEqual(called, true);\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n\n    this.client.start();\n  });\n\n\n  it('testPageObject navigate with url as a function using api object', function (done) {\n    MockServer.addMock({\n      'url': '/wd/hub/session/1352110219202/url',\n      postdata: {'url': 'https://nightwatchjs.org'},\n      'response': JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0\n      })\n    }, true);\n\n    const page = this.client.api.page.simplePageObj();\n    page.api.launch_url = 'https://nightwatchjs.org';\n\n    page.url = function (url) {\n      return this.api.launch_url;\n    };\n\n    page.navigate(function (result) {\n      //check if callback function is called\n      assert.strictEqual(result.status, 0);\n      done();\n    });\n\n    this.client.start();\n  });\n});\n\n"
  },
  {
    "path": "test/src/core/testPageObjectCustomCommands.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst MockServer = require('../../lib/mockserver.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test PageObject Custom Commands', function () {\n  before(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', function () {\n      done();\n    });\n  });\n\n  after(function (done) {\n    this.server.close(function () {\n      done();\n    });\n  });\n\n  beforeEach(function (done) {\n    Nightwatch.init({\n      page_objects_path: path.join(__dirname, '../../extra/pageobjects/pages'),\n      custom_commands_path: [path.join(__dirname, '../../extra/commands')]\n    }, function () {\n      done();\n    });\n\n    this.client = Nightwatch.client();\n  });\n\n  it('testPageObjectCustomCommands', function (done) {\n    let api = this.client.api;\n    let page = api.page.simplePageObj();\n\n    page\n      .waitForElementPresent('#weblogin', 1000, true, function callback(result) {\n        assert.strictEqual(this, api, 'page callback context using selector should equal api');\n      })\n      // just make sure page object contains custom command\n      .customPerform(function () {\n        done();\n      });\n\n    this.client.start();\n  });\n\n  it('testPageObject - custom commands object definition', function () {\n    let api = this.client.api;\n\n    const page = api.page.simplePageObjWithCommandsObject();\n    assert.strictEqual(typeof page.dropdownSelect, 'function');\n    assert.strictEqual(typeof page.testCommand, 'function');\n    assert.strictEqual(typeof page.getUrl, 'function');\n\n  });\n\n  it('testPageObject - custom commands class definition', function () {\n    let api = this.client.api;\n\n    const page = api.page.simplePageObjWithCommandsClass();\n\n    assert.strictEqual(typeof page.basicCommand, 'function');\n    assert.strictEqual(typeof page.dropdownSelectByText, 'function');\n    assert.strictEqual(typeof page.dropdownSelect, 'function');\n    assert.strictEqual(typeof page.scrollToElement, 'function');\n    assert.strictEqual(page.name, 'simplePageObjWithCommandsClass');\n    assert.strictEqual(typeof page.getUrl, 'function');\n\n    const result = page.basicCommand();\n    assert.deepStrictEqual(result, {\n      basicResult: 'from-helper-class',\n      otherResult: 'from-other-helper-class'\n    });\n\n  });\n\n  it('testPageObject - custom commands class definition - throws Error', function () {\n    let api = this.client.api;\n    let expectedError;\n    try {\n      const page = api.page.simplePageObjWithCommandsClassThrowsError();\n    } catch (err) {\n      expectedError = err;\n    }\n\n    assert.ok(expectedError instanceof Error, 'Expected error was not thrown');\n    assert.strictEqual(expectedError.message, 'Trying to overwrite page object/section \"simplePageObjWithCommandsClassThrowsError\"  method/property \"name\".');\n    assert.strictEqual(expectedError.detailedErr, 'Using basicCommand,dropdownSelect,dropdownSelectByText,name.');\n  });\n\n  it('testPageObject - custom command with args[0] as Array', function () {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute',\n      method: 'POST'\n    });\n    let api = this.client.api;\n\n    const page = api.page.simplePageObjWithCommandsObject().customExecute(['test']);\n\n    return this.client.start();\n  });\n\n  it('testPageObject - custom command with args[0] as Object', function () {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute',\n      method: 'POST'\n    });\n    let api = this.client.api;\n\n    const page = api.page.simplePageObjWithCommandsObject().customExecute({prop: true});\n\n    return this.client.start();\n  });\n\n  it('testPageObject - error loading custom commands', function (done) {\n    let api = this.client.api;\n\n    try {\n      api.page.simplePageObjWithError();\n    } catch (err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.message, 'Trying to overwrite page object/section \"simplePageObjWithError\"  method/property \"name\".');\n      assert.strictEqual(err.detailedErr, 'Using dropdownSelect, dropdownSelectByText, scrollToElement, name, testCommand.');\n\n      done();\n    }\n  });\n});\n\n"
  },
  {
    "path": "test/src/core/testPageObjectWaitForElementNotPresent.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst Nocks = require('../../lib/nocks.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\nxdescribe('test PageObject WaitForElementNotPresent', function () {\n  beforeEach(function (done) {\n    Nocks.enable().cleanAll().createSession();\n    Nightwatch.init({\n      page_objects_path: path.join(__dirname, '../../extra/pageobjects/pages')\n    }, function () {\n      done();\n    });\n    this.client = Nightwatch.client();\n  });\n\n  afterEach(function () {\n    Nocks.deleteSession().disable();\n  });\n\n  it('WaitForElementNotPresent with section', async function() {\n    Nocks.elementFound().click().elementFound().childElementsFound('#badElement').elementFound().childElementsNotFound()\n\n    const page = this.client.api.page.waitForElementNotPresentPageObj();\n\n    let res;\n    page.waitForElementNotPresentDemo(function(result) {\n      res = result;\n    })\n  \n    await this.client.start();\n    assert.equal(res.status, 0);\n  });\n});\n"
  },
  {
    "path": "test/src/core/testPlugins.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../lib/nightwatch.js');\ndescribe('test nightwatch plugins', function() {\n  \n  it('nightwatch-axe plugin should be loaded by default', async function() {\n    const client = Nightwatch.createClient({});\n    await client.initialize();\n\n    assert.ok('axeInject' in client.api);\n    assert.ok('axeRun' in client.api);\n    assert.strictEqual(typeof client.api.axeInject, 'function');\n    assert.strictEqual(typeof client.api.axeInject, 'function');\n  });\n});\n"
  },
  {
    "path": "test/src/core/testQueue.js",
    "content": "const assert = require('assert');\nconst Globals = require('../../lib/globals/expect.js');\nconst Nocks = require('../../lib/nocks.js');\n\ndescribe('test Queue', function () {\n  beforeEach(function (done) {\n    Globals.beforeEach.call(this, {\n      silent: true,\n      output: false\n    }, () => {\n      this.client.queue.reset();\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    Globals.afterEach.call(this, done);\n  });\n\n  it('Test commands queue', function () {\n    let client = this.client;\n    let queue = client.queue;\n    let urlCommand;\n    let endCommand;\n    Nocks.url().deleteSession();\n\n    client.api.url('http://localhost').end();\n\n    assert.strictEqual(queue.tree.rootNode.childNodes.length, 2);\n    urlCommand = queue.tree.rootNode.childNodes[0];\n    endCommand = queue.tree.rootNode.childNodes[1];\n\n    assert.strictEqual(endCommand.done, false);\n    assert.strictEqual(urlCommand.done, false);\n    assert.strictEqual(endCommand.started, false);\n\n    return this.client.start(err => {\n      if (err) {\n        throw err;\n      }\n      assert.strictEqual(urlCommand.started, true);\n      assert.strictEqual(urlCommand.done, true);\n      assert.strictEqual(endCommand.childNodes.length, 1);\n      assert.strictEqual(endCommand.done, true);\n      assert.strictEqual(queue.tree.rootNode.childNodes.length, 0);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/core/testRequestWithCredentials.js",
    "content": "const assert = require('assert');\nconst nock = require('nock');\nconst Nocks = require('../../lib/nocks.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test Request With Credentials', function () {\n  beforeEach(function () {\n    Nocks.cleanAll();\n    try {\n      Nocks.enable();\n    } catch (e) {\n    }\n\n  });\n\n  afterEach(function () {\n    Nocks.deleteSession();\n  });\n\n  after(function() {\n    Nocks.disable();\n  });\n\n  it('Test initialization with credentials', async function () {\n    nock('http://localhost:10195')\n      .post('/wd/hub/session')\n      .basicAuth({\n        user: 'testusername',\n        pass: '123456'\n      })\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'firefox',\n          version: 'TEST',\n          platform: 'TEST'\n        }\n      });\n\n    let client = Nightwatch.createClient({\n      selenium_port: 10195,\n      silent: false,\n      output: false,\n      username: 'testusername',\n      access_key: '123456'\n    });\n\n    client.on('nightwatch:session.create', function (data) {\n      assert.strictEqual(data.sessionId, '1352110219202');\n    });\n\n    await client.createSession();\n  });\n});\n"
  },
  {
    "path": "test/src/core/testTreeNode.js",
    "content": "const assert = require('assert');\nconst EventEmitter = require('events');\nconst common = require('../../common.js');\nconst TreeNode = common.require('core/treenode');\n\ndescribe('test Queue', function () {\n  it('Test commands treeNode - clear error events in handleCommandResult', function () {\n    const treeNode = new TreeNode({\n      name: '__root__',\n      parent: null\n    });\n\n    class MockCommandLoader extends EventEmitter {\n      constructor() {\n        super();\n        this.__commandName = 'testCommand';\n      }\n    }\n\n    const mockCommandLoader = new MockCommandLoader();\n\n    treeNode.setCommand(()=>{}, mockCommandLoader, {}, {});\n\n    treeNode.execute();\n    treeNode.execute();\n    treeNode.execute();\n\n    assert.equal(mockCommandLoader.listenerCount('error'), 3);\n    assert.equal(mockCommandLoader.listenerCount('complete'), 3);\n    \n    mockCommandLoader.emit('complete');\n\n    assert.equal(mockCommandLoader.listenerCount('error'), 0);\n    assert.equal(mockCommandLoader.listenerCount('complete'), 0);   \n    \n    \n    treeNode.execute();\n    treeNode.execute();\n    treeNode.execute();\n\n    assert.equal(mockCommandLoader.listenerCount('error'), 3);\n    assert.equal(mockCommandLoader.listenerCount('complete'), 3);\n\n    mockCommandLoader.emit('error', new Error(), false);\n\n    assert.equal(mockCommandLoader.listenerCount('error'), 0);\n    assert.equal(mockCommandLoader.listenerCount('complete'), 0);  \n  });\n\n  it('test handleError - set abortOnFailure to false in debug mode', function () {\n    const treeNode = new TreeNode({\n      name: '__root__',\n      parent: null\n    });\n    const Debuggability = common.require('utils/debuggability');\n\n    Debuggability.debugMode = true;\n    let error = new Error('Error while executing command in debug mode');\n    error.abortOnFailure = true;\n\n    error = treeNode.handleError(error);\n    assert.strictEqual(error.abortOnFailure, false);\n\n    Debuggability.debugMode = false;\n  });\n});\n"
  },
  {
    "path": "test/src/element/testCommandsElementSelectors.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst nocks = require('../../lib/nockselements.js');\nconst Nocks = require('../../lib/nocks.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test commands element selectors', function() {\n  after(function(done) {\n    nocks.disable();\n    nocks.cleanAll();\n    done();\n  });\n\n  before(function (done) {\n    nocks.enable();\n    done();\n  });\n\n  beforeEach(function (done) {\n    nocks.cleanAll().createSession();\n    Nightwatch.init({\n      output: false,\n      silent: false,\n      globals: {\n        waitForConditionTimeout: 100,\n        waitForConditionPollInterval: 10\n      },\n      page_objects_path: [path.join(__dirname, '../../extra/pageobjects/pages')]\n    }, done);\n  });\n\n  // wrapped selenium command\n\n  it('getText(<various>)', function(done) {\n    nocks\n      .elementsFound('#nock')\n      .elementsNotFound('#nock-none')\n      .elementsByXpath('//[@id=\"nock\"]')\n      .text(0, 'first')\n      .text(1, 'second');\n\n    Nightwatch.api()\n      .getText('#nock', function callback(result) {\n        assert.strictEqual(result.value, 'first');\n      })\n      .getText({selector: '#nock'}, function callback(result) {\n        assert.strictEqual(result.value, 'first');\n      })\n      .getText({selector: '#nock', index: 1}, function callback(result) {\n        assert.strictEqual(result.value, 'second');\n      })\n      .getText({selector: '#nock-none', timeout: 19}, function callback(result) {\n        assert.strictEqual(result.status, -1);\n      })\n      .getText({selector: '//[@id=\"nock\"]', locateStrategy: 'xpath'}, function callback(result) {\n        assert.strictEqual(result.value, 'first');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('getText(<various>) locateStrategy', function(done) {\n    nocks\n      .elementsFound('#nock')\n      .elementsByXpath('//[@id=\"nock\"]')\n      .text(0, 'first')\n      .text(1, 'second');\n\n    Nightwatch.api()\n      .useCss()\n      .getText('#nock', function callback(result) {\n        assert.strictEqual(result.value, 'first');\n      })\n      .useXpath()\n      .getText('//[@id=\"nock\"]', function callback(result) {\n        assert.strictEqual(result.value, 'first');\n      })\n      .useCss()\n      .getText({selector: '//[@id=\"nock\"]', locateStrategy: 'xpath'}, function callback(result) {\n        assert.strictEqual(result.value, 'first');\n      })\n      .getText({selector: '//[@id=\"nock\"]', locateStrategy: 'xpath', index: 1}, function callback(result) {\n        assert.strictEqual(result.value, 'second');\n      })\n      .getText('#nock', function callback(result) {\n        assert.strictEqual(result.value, 'first');\n      })\n      .getText('css selector', {selector: '//[@id=\"nock\"]', locateStrategy: 'xpath'}, function callback(result) {\n        assert.strictEqual(result.value, 'first');\n      })\n      .getText('xpath', {selector: '//[@id=\"nock\"]'}, function callback(result) {\n        assert.strictEqual(result.value, 'first');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('waitForElementPresent(<various>)', function(done) {\n    nocks.elementsFound();\n\n    Nightwatch.api()\n      .waitForElementPresent('.nock', 1, false, function callback(result) {\n        assert.strictEqual(result.value.length, 1);\n      })\n      .waitForElementPresent({selector: '.nock'}, 1, false, function callback(result) {\n        assert.strictEqual(result.value.length, 1);\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('waitForElementPresent(<string>) failure', function(done) {\n    nocks.elementsNotFound();\n\n    Nightwatch.api()\n      .waitForElementPresent('.nock-none', 1, false, function callback(result) {\n        assert.strictEqual(result.value, null, 'waitforPresent result expected null');\n      });\n\n    Nightwatch.start(function(err) {\n      if (err && err.name !== 'NightwatchAssertError') {\n        done(err);\n      } else {\n        done();\n      }\n    });\n  });\n\n  it('waitForElementPresent(<{selector}>) failure', function(done) {\n    nocks.elementsNotFound();\n\n    Nightwatch.api()\n      .waitForElementPresent({selector: '.nock-none'}, 1, false, function callback(result) {\n        assert.strictEqual(result.value, null, 'waitforPresent selector property result expected false');\n      });\n\n    Nightwatch.start(function(err) {\n      if (err && err.name !== 'NightwatchAssertError') {\n        done(err);\n      } else {\n        done();\n      }\n    });\n  });\n\n  it('waitForElementPresent(<various>) locateStrategy', function(done) {\n    nocks\n      .elementsFound()\n      .elementsNotFound()\n      .elementsByXpath();\n\n    Nightwatch.api()\n      .useCss()\n      .waitForElementPresent('.nock', 1, false, function callback(result) {\n        assert.strictEqual(result.value.length, 1, 'waitforPresent using css');\n      })\n      .useXpath()\n      .waitForElementPresent('//[@class=\"nock\"]', 1, false, function callback(result) {\n        assert.strictEqual(result.value.length, 1, 'waitforPresent using xpath');\n      })\n      .useCss()\n      .waitForElementPresent({selector: '//[@class=\"nock\"]', locateStrategy: 'xpath'}, 1, false, function callback(result) {\n        assert.strictEqual(result.value.length, 1, 'waitforPresent locateStrategy override to xpath found');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('waitForElementNotPresent(<{selector}>) success', function(done) {\n    Nocks\n      .elementsFound('.nock-string')\n      .elementsNotFound('.nock-string')\n      .elementsFound('.nock-object')\n      .elementsNotFound('.nock-object');\n\n    Nightwatch.api()\n      .waitForElementNotPresent('.nock-string', 150, false, function callback(result) {\n        assert.strictEqual(result.status, -1, 'waitForElementNotPresent succeeds');\n        assert.strictEqual(result.value, null, 'waitForElementNotPresent returns no elements');\n      })\n      .waitForElementNotPresent({selector: '.nock-object', timeout: 50, retryInterval: 20, abortOnFailure: false}, function callback(result) {\n        assert.strictEqual(result.status, -1, 'waitForElementNotPresent succeeds');\n        assert.strictEqual(result.value, null, 'waitForElementNotPresent returns no elements');\n      });\n\n    Nightwatch.start(function(err) {\n      if (err && err.name !== 'NightwatchAssertError') {\n        done(err);\n      } else {\n        done();\n      }\n    });\n  });\n\n  it('waitForElementNotPresent(<{selector}>) failure', function(done) {\n    nocks\n      .elementsFound('.nock-string')\n      .elementsFound('.nock-object');\n\n    Nightwatch.api()\n      .waitForElementNotPresent('.nock-string', 50, 20, false, function callback(result) {\n        assert.strictEqual(result.status, 0, 'waitForElementNotPresent \"succeeds\"');\n        assert.strictEqual(result.value.length, 1, 'waitForElementNotPresent returns the found elements');\n      })\n      .waitForElementNotPresent({selector: '.nock-object', timeout: 50, retryInterval: 20, abortOnFailure: false}, function callback(result) {\n        assert.strictEqual(result.status, 0, 'waitForElementNotPresent \"succeeds\"');\n        assert.strictEqual(result.value.length, 1, 'waitForElementNotPresent returns the found elements');\n      });\n\n    Nightwatch.start(function(err) {\n      if (err && err.name !== 'NightwatchAssertError') {\n        done(err);\n      } else {\n        done();\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/element/testElementCommands.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../lib/nightwatch.js');\nconst MockServer  = require('../../lib/mockserver.js');\nconst common = require('../../common.js');\nconst SimplifiedReporter = common.require('reporter/simplified.js');\n\ndescribe('element base commands', function() {\n  before(function(done) {\n    Nightwatch.startMockServer(done);\n  });\n\n  after(function(done) {\n    Nightwatch.stop(done);\n  });\n\n  class Reporter extends SimplifiedReporter {\n    constructor(settings) {\n      super(settings);\n\n      this.errors = 0;\n    }\n\n    registerTestError(err) {\n      this.errors++;\n    }\n  }\n\n  const reporter = new Reporter({});\n\n  //////////////////////////////////////////////////////////////////////////////////////\n  // .element()\n  //////////////////////////////////////////////////////////////////////////////////////\n  it('client.element()', async function() {\n    await Nightwatch.initAsync({\n      backwards_compatibility_mode: true,\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .element('css selector', '#weblogin', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value, {ELEMENT: '0'});\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.element() - unhandled error', async function() {\n    const client = await Nightwatch.initClient({\n      backwards_compatibility_mode: true,\n      output: false,\n      silent: false,\n      webdriver: {\n        timeout_options: {\n          retry_attempts: 0\n        }\n      }\n    }, reporter);\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element',\n      statusCode: 500,\n      postdata: {\n        using: 'css selector',\n        value: '#element-error'\n      },\n      response: {\n        sessionId: '1352110219202',\n        state: 'unhandled error',\n        value: {\n          message: 'test message'\n        },\n        status: 13\n      }\n    }, true);\n\n    client.api.element('css selector', '#element-error', function callback(result) {\n      assert.ok(result.error instanceof Error);\n      assert.strictEqual(result.status, -1);\n      assert.strictEqual(result.error.message, 'test message');\n      assert.strictEqual(result.error.name, 'WebDriverError');\n    });\n\n    await new Promise((resolve, reject) => {\n      client.start(err => {\n        if (err) {\n          reject(err);\n        } else {\n          resolve();\n        }\n      });\n    });\n    assert.strictEqual(client.reporter.errors, 0);\n  });\n\n  it('client.element() W3C Webdriver protocol', async function () {\n    const client = await Nightwatch.initAsync({\n      backwards_compatibility_mode: true,\n      output: false,\n      silent: false,\n      selenium: {\n        host: null\n      }\n    });\n\n    await Nightwatch.api()\n      .element('css selector', '#webdriver', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value, {'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'});\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.element() with xpath', async function() {\n    Nightwatch.addMock({\n      url: '/session/13521-10219-202/element',\n      postdata: JSON.stringify({\n        using: 'xpath',\n        value: '//weblogin'\n      }),\n      response: {\n        value: {\n          'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n        }\n      }\n    }, true);\n\n    await Nightwatch.initAsync({\n      backwards_compatibility_mode: true,\n      output: false,\n      silent: false,\n      selenium: {\n        start_process: false,\n        host: null\n      }\n    });\n\n    await Nightwatch.api()\n      .element('xpath', '//weblogin', function callback(result) {\n        assert.deepStrictEqual(result.value, {\n          'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n        });\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.element() NOT FOUND with W3C Webdriver protocol', async function() {\n    Nightwatch.addMock({\n      url: '/session/13521-10219-202/element',\n      postdata: {\n        using: 'css selector',\n        value: '.not_found'\n      },\n      statusCode: 404,\n      response: {\n        value: {\n          error: 'no such element',\n          message: 'Unable to locate element: .not_found',\n          stacktrace: ''\n        }\n      }\n    }, true);\n\n    await Nightwatch.initAsync({\n      backwards_compatibility_mode: true,\n      output: false,\n      silent: false,\n      selenium: {\n        host: null\n      }\n    });\n\n    Nightwatch.api().element('css selector', '.not_found', function(result) {\n      assert.ok(result.error instanceof Error);\n      assert.strictEqual(result.error.message, 'Unable to locate element: .not_found');\n      assert.strictEqual(result.status, -1);\n      assert.strictEqual(result.value, null);\n      assert.strictEqual(result.httpStatusCode, undefined);\n    });\n\n    return Nightwatch.start();\n  });\n\n\n  it('client.element() with 502 gateway error', async function() {\n    Nightwatch.addMock({\n      url: '/session/13521-10219-202/element',\n      postdata: {\n        using: 'css selector',\n        value: '#weblogin-error'\n      },\n      contentType: 'text/plain',\n      statusCode: 502,\n      response: `<html>\n<head>\n<title>502 Bad Gateway</title>\n</head>\n<body></body>\n</html>`,\n      times: 3\n    });\n\n    await Nightwatch.initAsync({\n      backwards_compatibility_mode: true,\n      output: false,\n      silent: false,\n      selenium: {\n        host: null\n      },\n      webdriver: {\n        internal_server_error_retry_interval: 0\n      }\n    });\n\n    Nightwatch.api().element('css selector', '#weblogin-error', function(result) {\n      assert.strictEqual(result.status, -1);\n      assert.strictEqual(result.error instanceof Error, true);\n      assert.strictEqual(result.error.name, 'WebDriverError');\n      assert.strictEqual(result.value, null);\n    });\n\n    return Nightwatch.start();\n  });\n\n  //////////////////////////////////////////////////////////////////////////////////////\n  // .findElement()\n  //////////////////////////////////////////////////////////////////////////////////////\n  it('client.findElement()', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .findElement('#weblogin', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value.ELEMENT, '0');\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.findElement() with strategy', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .findElement({selector: '#weblogin', locateStrategy: 'css selector'}, function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value.ELEMENT, '0');\n      });\n\n    return Nightwatch.start();\n  });\n\n  //////////////////////////////////////////////////////////////////////////////////////\n  // .elements()\n  //////////////////////////////////////////////////////////////////////////////////////\n  it('client.elements()', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .elements('css selector', '#weblogin', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value, [{ELEMENT: '0'}]);\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.elements() W3C Webdriver protocol', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false,\n      selenium: {\n        host: null\n      }\n    });\n\n    await Nightwatch.api()\n      .elements('css selector', '#webdriver', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value, [{\n          'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n        }, {\n          'element-6066-11e4-a52e-4f735466cecf': '3783b042-7001-0740-a2c0-afdaac732e9f'\n        }]);\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.elements() with xpath', async function() {\n    Nightwatch.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: JSON.stringify({\n        using: 'xpath',\n        value: '//weblogin'\n      }),\n      response: {\n        value: [{\n          'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n        }, {\n          'element-6066-11e4-a52e-4f735466cecf': '3783b042-7001-0740-a2c0-afdaac732e9f'\n        }]\n      }\n    }, true);\n\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false,\n      selenium: {\n        host: null\n      }\n    });\n\n    await Nightwatch.api()\n      .elements('xpath', '//weblogin', function callback(result) {\n        assert.deepStrictEqual(result.value, [{\n          'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n        }, {\n          'element-6066-11e4-a52e-4f735466cecf': '3783b042-7001-0740-a2c0-afdaac732e9f'\n        }]);\n      });\n\n    return Nightwatch.start();\n  });\n\n  //////////////////////////////////////////////////////////////////////////////////////\n  // .findElements()\n  //////////////////////////////////////////////////////////////////////////////////////\n  it('client.findElements()', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .findElements({locateStrategy: 'css selector', selector: '#weblogin'}, function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.strictEqual(result.value.length, 1);\n        assert.strictEqual(result.value[0].ELEMENT, '0');\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.findElements() with default locate strategy', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .findElements('#weblogin', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.strictEqual(result.value.length, 1);\n        assert.strictEqual(result.value[0].ELEMENT, '0');\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.findElements() W3C Webdriver protocol', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false,\n      selenium: {\n        host: null\n      }\n    });\n\n    await Nightwatch.api()\n      .findElements('#webdriver', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.strictEqual(result.value.length, 2);\n        assert.strictEqual(result.value[0]['element-6066-11e4-a52e-4f735466cecf'], '5cc459b8-36a8-3042-8b4a-258883ea642b');\n        assert.strictEqual(result.value[1]['element-6066-11e4-a52e-4f735466cecf'], '3783b042-7001-0740-a2c0-afdaac732e9f');\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.findElements() with xpath', async function() {\n    Nightwatch.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: JSON.stringify({\n        using: 'xpath',\n        value: '//weblogin'\n      }),\n      response: {\n        value: [{\n          'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n        }, {\n          'element-6066-11e4-a52e-4f735466cecf': '3783b042-7001-0740-a2c0-afdaac732e9f'\n        }]\n      }\n    }, true);\n\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false,\n      selenium: {\n        host: null\n      }\n    });\n\n    await Nightwatch.api()\n      .findElements({locateStrategy: 'xpath', selector: '//weblogin'}, function callback(result) {\n        assert.strictEqual(result.value.length, 2);\n        assert.strictEqual(result.value[0]['element-6066-11e4-a52e-4f735466cecf'], '5cc459b8-36a8-3042-8b4a-258883ea642b');\n        assert.strictEqual(result.value[1]['element-6066-11e4-a52e-4f735466cecf'], '3783b042-7001-0740-a2c0-afdaac732e9f');\n      });\n\n    return Nightwatch.start();\n  });\n\n  //////////////////////////////////////////////////////////////////////////////////////\n  // .elementIdElement()\n  //////////////////////////////////////////////////////////////////////////////////////\n  it('client.elementIdElement()', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .elementIdElement('0', 'css selector', '#helpBtn', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value, {ELEMENT: '1'});\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.elementIdElement() with selector object', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .elementIdElement('0', 'css selector', {selector: '#helpBtn'}, function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value, {ELEMENT: '1'});\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.elementIdElement() with wrong selector object', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    let thrown;\n\n    try {\n      await Nightwatch.api().elementIdElement('0', 'css selector', {});\n      await Nightwatch.start();\n    } catch (err) {\n      thrown = err;\n    }\n\n    assert.ok(thrown instanceof Error);\n    assert.ok(thrown.message.includes('No selector property for selector object'));\n  });\n\n  //////////////////////////////////////////////////////////////////////////////////////\n  // .elementIdElements()\n  //////////////////////////////////////////////////////////////////////////////////////\n  it('client.elementIdElements()', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .elementIdElements('0', 'css selector', '.btn', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value, [{ELEMENT: '1'}, {ELEMENT: '2'}, {ELEMENT: '3'}]);\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.elementIdElements() with index', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .elementIdElements('0', 'css selector', {selector: '.btn', index: 1}, function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.deepStrictEqual(result.value, [{ELEMENT: '2'}]);\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.elementIdElements() with wrong index', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    await Nightwatch.api()\n      .elementIdElements('0', 'css selector', {selector: '.btn', index: 4}, function callback(result) {\n        assert.strictEqual(result.status, -1);\n        assert.strictEqual(result.value, null);\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('client.elementIdElements() with wrong selector object', async function() {\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false\n    });\n\n    let thrown;\n\n    try {\n      await Nightwatch.api().elementIdElements('0', 'css selector', {});\n      await Nightwatch.start();\n    } catch (err) {\n      thrown = err;\n    }\n\n    assert.ok(thrown instanceof Error);\n    assert.ok(thrown.message.includes('No selector property for selector object'));\n  });\n\n  //////////////////////////////////////////////////////////////////////////////////////\n  // .isVisible({selector, suppressNotFoundErrors})\n  //////////////////////////////////////////////////////////////////////////////////////\n  it('client.isVisible() NOT FOUND with W3C Webdriver protocol', async function() {\n    Nightwatch.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '.not_found'\n      },\n      statusCode: 404,\n      response: {\n        value: {\n          error: 'no such element',\n          message: 'Unable to locate element: .not_found',\n          stacktrace: ''\n        }\n      }\n    }, true);\n\n    Nightwatch.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '.not_found'\n      },\n      statusCode: 404,\n      response: {\n        value: {\n          error: 'no such element',\n          message: 'Unable to locate element: .not_found',\n          stacktrace: ''\n        }\n      }\n    }, true);\n\n    let expectedError;\n\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false,\n      selenium: {\n        host: null\n      }\n    }, {\n      registerTestError(err) {\n        expectedError = err;\n      }\n    });\n\n    Nightwatch.api().isVisible({selector: '.not_found', timeout: 10, retryInterval: 100, suppressNotFoundErrors: false}, function(result, instance) {\n      assert.ok(expectedError instanceof Error);\n      assert.strictEqual(expectedError.name, 'NoSuchElementError');\n      assert.strictEqual(instance.suppressNotFoundErrors, false);\n      assert.strictEqual(result.status, -1);\n      assert.strictEqual(result.value.error, 'An error occurred while running .isVisible() command on <.not_found>: Timed out while waiting for element \".not_found\" with \"css selector\" to be present for 10 milliseconds.');\n    });\n\n    return Nightwatch.start();\n  });\n\n  it('client.isVisible() NOT FOUND with suppressed errors', async function() {\n    Nightwatch.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '.not_found'\n      },\n      statusCode: 404,\n      response: {\n        value: {\n          error: 'no such element',\n          message: 'Unable to locate element: .not_found',\n          stacktrace: ''\n        }\n      }\n    }, true);\n\n    Nightwatch.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '.not_found'\n      },\n      statusCode: 404,\n      response: {\n        value: {\n          error: 'no such element',\n          message: 'Unable to locate element: .not_found',\n          stacktrace: ''\n        }\n      }\n    }, true);\n\n    let expectedError;\n\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false,\n      selenium: {\n        host: null\n      }\n    }, {\n      registerTestError(err) {\n        expectedError = err;\n      }\n    });\n\n    Nightwatch.api().isVisible({selector: '.not_found', timeout: 10, retryInterval: 100, suppressNotFoundErrors: true}, function(result, instance) {\n      assert.strictEqual(typeof expectedError, 'undefined');\n      assert.strictEqual(instance.suppressNotFoundErrors, true);\n      assert.strictEqual(result.status, -1);\n      assert.strictEqual(result.value, null);\n      assert.ok(result.error instanceof Error);\n    });\n\n    return Nightwatch.start();\n  });\n});\n"
  },
  {
    "path": "test/src/element/testExpectElementSelectors.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst nocks = require('../../lib/nockselements.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test expect element selectors', function() {\n\n  before(() => nocks.enable());\n  after(function(done) {\n    nocks.disable();\n    nocks.cleanAll();\n    done();\n  });\n\n  beforeEach(function (done) {\n    nocks.cleanAll().createSession();\n    Nightwatch.init({\n      output: false,\n      silent: false,\n      page_objects_path: [path.join(__dirname, '../../extra/pageobjects/pages')]\n    }, done);\n  });\n\n  it('passing expect selectors', function (done) {\n    nocks\n      .elementsFound()\n      .elementsFound('#signupSection', [{ELEMENT: '0'}])\n      .elementsId(0, '#helpBtn', [{ELEMENT: '0'}, {ELEMENT: '1'}])\n      .elementsByXpath();\n\n    let api = Nightwatch.api();\n    api.globals.abortOnAssertionFailure = false;\n    api.globals.suppressWarningsOnMultipleElementsReturned = true;\n\n    let page = api.page.simplePageObj();\n    let section = page.section.signUp;\n\n    let passingAssertions = [\n      api.expect.element('.nock').to.be.present.before(1),\n      api.expect.element({selector: '.nock'}).to.be.present.before(1),\n      api.expect.element({selector: '//[@class=\"nock\"]', locateStrategy: 'xpath'}).to.be.present.before(1),\n      page.expect.section('@signUp').to.be.present.before(1),\n      page.expect.section({selector: '@signUp', locateStrategy: 'css selector'}).to.be.present.before(1),\n      section.expect.element('@help').to.be.present.before(1)\n    ];\n\n    api.perform(function() {\n      passingAssertions.forEach(function(expect, index) {\n        assert.strictEqual(expect.assertion.passed, true, 'passing [' + index + ']: ' + expect.assertion.message);\n      });\n    });\n\n    Nightwatch.start(done);\n  });\n\n\n  it('failing expect selectors - xpath .nock', function (done) {\n    nocks\n      .elementsFound()\n      .elementsByXpathError();\n\n    let api = Nightwatch.api();\n    api.globals.abortOnAssertionFailure = true;\n\n    let expect = api.expect.element({selector: '.nock', locateStrategy: 'xpath'}).to.be.present.before(1);\n\n    Nightwatch.start(function(err) {\n      assert.strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.includes('element was not found'));\n      assert.ok(err instanceof Error);\n      done();\n    });\n  });\n\n  it('unknown/invalid expect methods', function () {\n    nocks\n      .elementsFound()\n      .elementsFound('#signupSection', [{ELEMENT: '0'}]);\n\n    let api = Nightwatch.api();\n    api.globals.abortOnAssertionFailure = false;\n\n    assert.throws(function() {\n      api.expect.element('.nock').to.be.hidden;\n    }, /Error: Unknown property: \"hidden\"\\. Please consult docs at: https:\\/\\/nightwatchjs\\.org\\/api\\/expect/);\n\n    Nightwatch.start();\n  });\n\n  it('failing expect selectors - xpath @signUp', function () {\n    nocks\n      .elementsFound()\n      .elementsFound('#signupSection')\n      .elementsByXpath();\n\n    let api = Nightwatch.api();\n    api.globals.abortOnAssertionFailure = false;\n\n    let page = api.page.simplePageObj();\n    try {\n      page.expect.section({selector: '@signUp', locateStrategy: 'xpath'}).to.be.present;\n    } catch (err) {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.message, 'Section \"signUp[locateStrategy=\\'xpath\\']\" was not found in \"simplePageObj\". Available sections: signUp[locateStrategy=\\'css selector\\'], propTest[locateStrategy=\\'css selector\\']');\n    }\n    Nightwatch.start();\n  });\n});\n"
  },
  {
    "path": "test/src/element/testIndexedElementSelectors.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst nocks = require('../../lib/nockselements.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test index in element selectors', function() {\n  before(function() {\n    nocks.enable();\n  });\n\n  after(function(done) {\n    nocks.disable();\n    nocks.cleanAll();\n    done();\n  });\n\n  beforeEach(function (done) {\n    nocks.cleanAll().createSession();\n    Nightwatch.init({\n      output: false,\n      silent: false,\n      page_objects_path: [path.join(__dirname, '../../extra/pageobjects/pages')]\n    }, done);\n  });\n\n  it('calling protocol.elements(using, {selector, index})', function (done) {\n    nocks.elementsFound();\n\n    Nightwatch.api()\n      .elements('css selector', {selector: '.nock', index: 0}, function callback(result) {\n        assert.strictEqual(result.value.length, 1, 'found index, one element');\n        assert.strictEqual(result.value[0].ELEMENT, '0', 'Found element 0');\n      })\n      .elements('css selector', {selector: '.nock', index: 1}, function callback(result) {\n        assert.strictEqual(result.value.length, 1, 'found index, one element');\n        assert.strictEqual(result.value[0].ELEMENT, '1', 'Found element 1');\n      })\n      .elements('css selector', {selector: '.nock', index: 2}, function callback(result) {\n        assert.strictEqual(result.value.length, 1, 'found index, one element');\n        assert.strictEqual(result.value[0].ELEMENT, '2', 'Found element 2');\n      })\n      .elements('css selector', {selector: '.nock', index: 999}, function callback(result) {\n        assert.strictEqual(result.value, null, 'Out of range index, empty result set');\n        assert.strictEqual(result.status, -1, 'Not found for out of range index');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  // wrapped selenium command\n\n  it('calling getText(<various>, {index})', function (done) {\n    nocks\n      .elementsFound()\n      .elementsByXpath()\n      .text(0, 'first')\n      .text(1, 'second');\n\n    Nightwatch.api()\n      .getText({selector: '.nock', index: 1}, function callback(result) {\n        assert.strictEqual(result.value, 'second', 'getText index 1');\n      })\n      .getText({selector: '//[@class=\"nock\"]', locateStrategy: 'xpath', index: 1}, function callback(result) {\n        assert.strictEqual(result.value, 'second', 'getText xpath locateStrategy index 1');\n      })\n      .getText({\n        selector: '//[@class=\"nock\"]',\n        locateStrategy: 'xpath',\n        index: 999,\n        timeout: 50,\n        retryInterval: 10\n      }, function callback(result) {\n        assert.strictEqual(result.status, -1, 'getText xpath locateStrategy out of range index');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  // custom command\n\n  it('calling waitForElementPresent(<various>, {index})', function (done) {\n    nocks\n      .elementsFound();\n\n    Nightwatch.api()\n      .waitForElementPresent({selector: '.nock', index: 1}, 1, false, function callback(result) {\n        assert.strictEqual(result.value.length, 1, 'waitforPresent index has results');\n        assert.strictEqual(result.value[0].ELEMENT, '1', 'waitforPresent found element 1');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('calling waitForElementPresent(<various>, {index}) failure', function (done) {\n    nocks\n      .elementsFound();\n\n    Nightwatch.api()\n      .waitForElementPresent({selector: '.nock', index: 999, retryInterval: 10}, 1, false, function callback(result) {\n        assert.strictEqual(result.value, null, 'waitforPresent out of bounds index expected false');\n      });\n\n    Nightwatch.start(function(err) {\n      if (err && err.name !== 'NightwatchAssertError') {\n        done(err);\n      } else {\n        done();\n      }\n    });\n  });\n\n  it('using page elements with index', function (done) {\n    nocks\n      .elementsFound('#weblogin')\n      .text(0, 'first')\n      .text(1, 'second');\n\n    let page = Nightwatch.api().page.simplePageObj();\n\n    page\n      .getText('@loginIndexed', function callback(result) {\n        assert.strictEqual(result.status, 0, 'status for element indexed found');\n        assert.strictEqual(result.value, 'second', 'element indexed value');\n      })\n      .getText({selector: '@loginIndexed', index: 0}, function callback(result) {\n        assert.strictEqual(result.status, 0, 'status for element index 0 override found');\n        assert.strictEqual(result.value, 'first', 'element index overridde value');\n      })\n      .getText({selector: '@loginCss', index: 1}, function callback(result) {\n        assert.strictEqual(result.status, 0, 'status for element selector index 1 found');\n        assert.strictEqual(result.value, 'second', 'element selector index 1 value');\n      })\n      .getText({selector: '@loginCss', index: 999, timeout: 20, retryInterval: 10}, function callback(result) {\n        assert.strictEqual(result.status, -1, 'element selector index out of bounds not found');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('using page section elements with index', function (done) {\n    nocks\n      .elementsFound('#signupSection') // page.section\n      .elementsId(0, '#helpBtn', [{ELEMENT: '1'}, {ELEMENT: '2'}])\n      .elementsId(0, '#helpBtn:nth-child(1)', [{ELEMENT: '1'}])\n      .elementId(0, '#helpBtn', null, {ELEMENT: '1'})\n      .text(1, 'help-first')\n      .text(2, 'help-second')\n      .elementsId(0, '#getStarted', [{ELEMENT: '10'}]) // page.section.section\n      .elementId(0, '#getStarted', null, {ELEMENT: '10'})\n      .elementsId(10, '#getStartedStart', [{ELEMENT: '11'}]) // page.section.section.element\n      .elementsId(10, '#getStartedStart:nth-child(1)', [{ELEMENT: '11'}]) // page.section.section.element\n      .elementId(10, '#getStartedStart', null, {ELEMENT: '11'})\n      .text(11, 'start-first');\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n    let sectionChild = section.section.getStarted;\n\n    section\n      .getText({selector: '@help'}, function callback(result) {\n        assert.strictEqual(result.status, 0, 'section element selector found');\n        assert.strictEqual(result.value, 'help-first', 'section element selector value');\n      })\n      .getText({selector: '@help:nth-child(1)'}, function callback(result) {\n        assert.strictEqual(result.status, 0, 'section element selector found');\n        assert.strictEqual(result.value, 'help-first', 'section element selector value');\n      })\n      .getText({selector: '@help', index: 1}, function callback(result) {\n        assert.strictEqual(result.status, 0, 'section element selector index 1 found');\n        assert.strictEqual(result.value, 'help-second', 'section element selector index 1 value');\n      })\n      .getText({selector: '@help', index: 999, timeout: 20, retryInterval: 15}, function callback(result) {\n        assert.strictEqual(result.status, -1, 'section element selector index out of bounds not found');\n      });\n\n    sectionChild\n      .getText({selector: '@start'}, function callback(result) {\n        assert.strictEqual(result.status, 0, 'child section element selector found');\n        assert.strictEqual(result.value, 'start-first', 'child section element selector value');\n      })\n      .getText({selector: '@start', index: 0}, function callback(result) {\n        assert.strictEqual(result.status, 0, 'child section element selector index 0 found');\n        assert.strictEqual(result.value, 'start-first', 'child section element selector index 0 value');\n      })\n      .getText('@start:nth-child(1)', function callback(result) {\n        assert.strictEqual(result.status, 0, 'child section element selector index 0 found');\n        assert.strictEqual(result.value, 'start-first', 'child section element selector index 0 value');\n      })\n      .getText({selector: '@start', index: 999, timeout: 20, retryInterval: 15}, function callback(result) {\n        assert.strictEqual(result.status, -1, 'child section element selector index out of bounds not found');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('using expect selectors with index - passing assertions', function (done) {\n    nocks\n      .elementsFound()\n      .elementsFound('#signupSection', [{ELEMENT: '0'}])\n      .elementsId(0, '#helpBtn', [{ELEMENT: '0'}])\n      .elementsByXpath();\n\n    let api = Nightwatch.api();\n    api.globals.abortOnAssertionFailure = false;\n\n    let page = api.page.simplePageObj();\n    let section = page.section.signUp;\n\n    let passingAssertions = [\n      api.expect.element({selector: '.nock', index: 2}).to.be.present.before(1),\n      page.expect.section({selector: '@signUp', locateStrategy: 'css selector', index: 0}).to.be.present.before(1),\n      section.expect.element({selector: '@help', index: 0}).to.be.present.before(1)\n    ];\n\n    api.perform(function() {\n      passingAssertions.forEach(function(expect, index) {\n        assert.strictEqual(expect.assertion.passed, true, 'passing [' + index + ']: ' + expect.assertion.message);\n      });\n    });\n\n    Nightwatch.start(done);\n  });\n\n  it('using expect selectors with index - failing .nock', function (done) {\n    nocks.elementsFound();\n\n    let api = Nightwatch.api();\n    let expect = api.expect.element({selector: '.nock', index: 999}).to.be.present.before(1);\n\n    Nightwatch.start(function(err) {\n      try {\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.includes('element was not found'));\n        assert.strictEqual(err instanceof Error, true);\n        nocks.checkIfMocksDone();\n        done();\n      } catch (ex) {\n        done(ex);\n      }\n    });\n  });\n\n  it('using expect selectors with index - failing @help', function (done) {\n    nocks\n      .elementsFound('#signupSection', [{ELEMENT: '0'}])\n      .elementsId(0, '#helpBtn', [{ELEMENT: '0'}]);\n\n    let api = Nightwatch.api();\n    api.globals.abortOnAssertionFailure = true;\n    let page = api.page.simplePageObj();\n    let section = page.section.signUp;\n\n    let expect = section.expect.element({selector: '@help', index: 999}).to.be.present.before(1);\n\n    Nightwatch.start(function(err) {\n\n      try {\n        assert.strictEqual(expect.assertion.passed, false);\n        assert.ok(expect.assertion.message.includes('element was not found'));\n        assert.ok(err instanceof Error);\n        nocks.checkIfMocksDone();\n        done();\n      } catch (ex) {\n        done(ex);\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/element/testPageObjectElementSelectors-use_xpath.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst nocks = require('../../lib/nockselements.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\nconst {strictEqual} = assert;\n\ndescribe('test page object element selectors with locateStrategy from nightwatch settings', function () {\n  before(function() {\n    nocks.enable();\n  });\n\n  after(function() {\n    nocks.disable();\n  });\n\n  beforeEach(function(done) {\n    nocks.cleanAll().enable().createSession();\n    done();\n  });\n\n  it('page object allows shorthand selector for xpath when \"use_xpath=true\"', async function () {\n    await Nightwatch.init({\n      page_objects_path: [path.join(__dirname, '../../extra/pageobjects/pages')],\n      custom_commands_path: [path.join(__dirname, '../../extra/commands')],\n      custom_assertions_path: [path.join(__dirname, '../../extra/assertions')],\n      use_xpath: true,\n      output: false,\n      silent: false,\n      globals: {\n        abortOnAssertionFailure: true\n      }\n    });\n\n    const page = Nightwatch.api().page.simplePageObjDefaultXpath();\n    assert.strictEqual(page.elements.xpathElement.locateStrategy, 'xpath');\n    assert.strictEqual(page.elements.xpathElement2.locateStrategy, 'xpath');\n    assert.strictEqual(page.elements.cssSelectorElement.locateStrategy, 'css selector');\n    assert.strictEqual(page.section.signUp.locateStrategy, 'xpath');\n    assert.strictEqual(page.section.signUp.elements.start.locateStrategy, 'css selector');\n\n    return new Promise((resolve, reject) => {\n      Nightwatch.start(function(err) {\n        if (err) {\n          return reject(err);\n        }\n        resolve();\n      });\n    });\n  });\n\n  it('page object defaults to css selector for shorthand when \"use_xpath=false\"', async function () {\n    await Nightwatch.init({\n      page_objects_path: [path.join(__dirname, '../../extra/pageobjects/pages')],\n      custom_commands_path: [path.join(__dirname, '../../extra/commands')],\n      custom_assertions_path: [path.join(__dirname, '../../extra/assertions')],\n      use_xpath: false,\n      output: false,\n      silent: false,\n      globals: {\n        abortOnAssertionFailure: true\n      }\n    });\n\n    const page = Nightwatch.api().page.simplePageObjDefaultXpath();\n    assert.strictEqual(page.elements.xpathElement.locateStrategy, 'css selector');\n    assert.strictEqual(page.elements.xpathElement2.locateStrategy, 'css selector');\n    assert.strictEqual(page.elements.cssSelectorElement.locateStrategy, 'css selector');\n    assert.strictEqual(page.section.signUp.locateStrategy, 'css selector');\n    assert.strictEqual(page.section.signUp.elements.start.locateStrategy, 'css selector');\n\n    return new Promise((resolve, reject) => {\n      Nightwatch.start(function(err) {\n        if (err) {\n          return reject(err);\n        }\n        resolve();\n      });\n    });\n  });\n\n  describe('elements', function () {\n    beforeEach(function (done) {\n      Nightwatch.init({\n        page_objects_path: [path.join(__dirname, '../../extra/pageobjects/pages')],\n        custom_commands_path: [path.join(__dirname, '../../extra/commands')],\n        custom_assertions_path: [path.join(__dirname, '../../extra/assertions')],\n        use_xpath: true,\n        output: false,\n        silent: false,\n        globals: {\n          abortOnAssertionFailure: true\n        }\n      }, done);\n    });\n\n    it('page object finds element', function (done) {\n      nocks\n        .elementsByXpath('//div')\n        .text('0', 'first');\n\n\n      let page = Nightwatch.api().page.simplePageObjDefaultXpath();\n\n      page\n        .getText('@xpathElement', function callback(result) {\n          strictEqual(result.status, 0);\n          strictEqual(result.value, 'first');\n        });\n      Nightwatch.start(done);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/element/testPageObjectElementSelectors.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst nocks = require('../../lib/nockselements.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\nconst {strictEqual} = assert;\n\nxdescribe('test page object element selectors', function() {\n\n  before(function() {\n    nocks.enable();\n  });\n\n  after(function() {\n    nocks.disable();\n  });\n\n  beforeEach(function(done) {\n    nocks.cleanAll().enable().createSession();\n\n    Nightwatch.init({\n      page_objects_path: [path.join(__dirname, '../../extra/pageobjects/pages')],\n      custom_commands_path: [path.join(__dirname, '../../extra/commands')],\n      custom_assertions_path: [path.join(__dirname, '../../extra/assertions')],\n      output: false,\n      silent: false,\n      globals: {\n        abortOnAssertionFailure: true,\n        waitForConditionTimeout: 100,\n        waitForConditionPollInterval: 60,\n        retryAssertionTimeout: 100\n      }\n    }, done);\n  });\n\n  it('page elements', function(done) {\n    nocks\n      .elementsFound('#weblogin')\n      .elementsFound('weblogin', [{ELEMENT: '0'}], 'id')\n      .elementsFound('*[id=\"weblogin\"]', [{ELEMENT: '0'}])\n      .elementsByXpath('//weblogin')\n      .elementsByXpath('#weblogin', [])\n      .text(0, 'first')\n      .text(1, 'second');\n\n    let page = Nightwatch.api().page.simplePageObj();\n\n    page\n      .getText('@loginAsString', function callback(result) {\n        strictEqual(result.status, 0, 'element selector string found');\n        strictEqual(result.value, 'first', 'element selector string value');\n      })\n      .getText({selector: '@loginAsString'}, function callback(result) {\n        strictEqual(result.status, 0, 'element selector property found');\n        strictEqual(result.value, 'first', 'element selector property value');\n      })\n      .getText('@loginXpath', function callback(result) {\n        strictEqual(result.status, 0, 'element selector xpath found');\n        strictEqual(result.value, 'first', 'element selector xpath value');\n      })\n      .getText('@loginCss', function callback(result) {\n        strictEqual(result.status, 0, 'element selector css found');\n        strictEqual(result.value, 'first', 'element selector css value');\n      })\n      .getText('@loginId', function callback(result) {\n        strictEqual(result.status, 0, 'element selector id found');\n        strictEqual(result.value, 'first', 'element selector id value');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('page section elements', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementsFound('#getStarted')\n      .elementsFound('#helpBtn')\n      .elementIdNotFound(0, '#helpBtn', 'xpath')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '0'}])\n      .text(0, 'first')\n      .text(1, 'second');\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n    let sectionChild = section.section.getStarted;\n\n    section\n      .getText('@help', function callback(result) {\n        strictEqual(result.status, 0, 'section element selector string found');\n        strictEqual(result.value, 'first', 'section element selector string value');\n      })\n      .getText({selector: '@help'}, function callback(result) {\n        strictEqual(result.status, 0, 'section element selector property found');\n        strictEqual(result.value, 'first', 'section element selector property value');\n      });\n\n    assert.throws(function() {\n      section.getText({selector: '@help', locateStrategy: 'xpath'});\n    }, /^Error: Element \"help\\[locateStrategy='xpath'\\]\" was not found in \"signUp\"/);\n\n    sectionChild\n      .getText('#helpBtn', function callback(result) {\n        strictEqual(result.status, 0, 'child section element selector string found');\n        strictEqual(result.value, 'first', 'child section element selector string value');\n      })\n      .getText({selector: '#helpBtn'}, function callback(result) {\n        strictEqual(result.status, 0, 'child section element selector property found');\n        strictEqual(result.value, 'first', 'child section element selector property value');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('page section custom commands', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementsId('0', '.btn', [{ELEMENT: '4'}, {ELEMENT: '5'}, {ELEMENT: '6'}])\n      .elementId('0', '#helpBtn');\n\n    const page = Nightwatch.api().page.simplePageObj();\n    const section = page.section.signUp;\n\n    section.sectionElement(function(result) {\n      assert.strictEqual(result.status, 0);\n      assert.deepStrictEqual(result.value, {ELEMENT: '0'});\n      assert.strictEqual(result.WebdriverElementId, '0');\n    });\n\n    section.sectionElements(function(result) {\n      assert.strictEqual(result.status, 0);\n      assert.deepStrictEqual(result.value, [{ELEMENT: '4'}, {ELEMENT: '5'}, {ELEMENT: '6'}]);\n      assert.strictEqual(result.WebdriverElementId, '4');\n    });\n\n    Nightwatch.start(done);\n  });\n\n  it('page section protocol .elements()', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '12345'}]);\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section.api.elements('@help', function callback(response) {\n      strictEqual(response.status, 0, 'section element selector string found');\n      strictEqual(response.value.length, 1);\n      assert.deepStrictEqual(response.value, [{ELEMENT: '12345'}]);\n    });\n\n    Nightwatch.start(done);\n  });\n\n  it('page section elements with css selectors', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementsNotFound('#helpBtn')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '0'}])\n      .text(0, 'first');\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section\n      .getText({selector: '#helpBtn', timeout: 100, retryInterval: 50}, function callback(result) {\n        strictEqual(result.status, 0);\n        strictEqual(result.value, 'first');\n      })\n      .getText({selector: '@help', timeout: 100, retryInterval: 50}, function callback(result) {\n        strictEqual(result.status, 0);\n        strictEqual(result.value, 'first');\n      });\n\n    section.expect.elements({\n      selector: '#helpBtn',\n      timeout: 100,\n      retryInterval: 50,\n      abortOnFailure: true\n    }).count.equal(1);\n\n    Nightwatch.start(done);\n  });\n\n  it('page section protocol .element()', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementId('0', '#helpBtn', 'css selector', {ELEMENT: '12345'});\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section.api.element('#helpBtn', function callback(response) {\n      strictEqual(response.status, 0, 'section element selector string found');\n      strictEqual(response.value.ELEMENT, '12345');\n      assert.deepStrictEqual(response.value, {ELEMENT: '12345'});\n    });\n\n    Nightwatch.start(done);\n  });\n\n  it('page section protocol .elementIdElements()', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '12345'}])\n      .elementsId('12345', 'a', [{ELEMENT: 'abc-12345'}]);\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section.api.elementIdElements('@help', 'css selector', 'a', function callback(response) {\n      strictEqual(response.status, 0, 'section element selector string not found');\n      assert.deepStrictEqual(response.value, [{ELEMENT: 'abc-12345'}]);\n    });\n\n    Nightwatch.start(done);\n  });\n\n  it('page section protocol .elementIdElement()', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '12345'}])\n      .elementId('12345', 'a', 'css selector', {ELEMENT: 'abc-12345'});\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section.api.elementIdElement('@help', 'css selector', 'a', function callback(response) {\n      strictEqual(response.status, 0, 'section element selector string found');\n      strictEqual(response.value.ELEMENT, 'abc-12345');\n    });\n\n    Nightwatch.start(done);\n  });\n\n  it('page section elements - section element not found', function() {\n    nocks\n      .elementsNotFound('#signupSection')\n      .elementsFound('#weblogin')\n      .elementFound('#weblogin')\n      .clearValue('0')\n      .elementsId('0', '#getStartedStart', [{ELEMENT: '1'}])\n      .text(0, 'first')\n      .text(1, 'second');\n\n    Nightwatch.api().globals.waitForConditionPollInterval = 10;\n\n    let page = Nightwatch.api().page.simplePageObj();\n    page.testCommand();\n    let section = page.section.signUp;\n\n    let expect = section.expect.element('@help').to.be.visible.before(15);\n\n    return Nightwatch.start(function(err) {\n      assert.ok(err instanceof Error, 'Expected err to be an Error but found: ' + typeof err);\n      strictEqual(err.name, 'NightwatchAssertError');\n      strictEqual(expect.assertion.passed, false);\n      assert.ok(expect.assertion.message.includes('Expected element <Section [name=signUp],Element [name=@help]> to be visible'));\n      assert.ok(expect.assertion.message.includes('element was not found'));\n    });\n  });\n\n  it('page object .not assert', function(done) {\n    nocks.elementsNotFound('#weblogin');\n\n    const page = Nightwatch.api().page.simplePageObj();\n    page.assert.not.elementPresent('@loginAsString');\n    page.verify.not.elementPresent('@loginAsString');\n\n    Nightwatch.start(function(err) {\n      assert.strictEqual(err, undefined);\n      done();\n    });\n  });\n\n  it('page object section .not assert', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementFound('#getStarted')\n      .elementFound('#helpBtn')\n      .elementsId('0', '#helpBtn', []);\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section.assert.not.elementPresent('@help', function(result) {\n      assert.strictEqual(result.passed, true);\n      done();\n    });\n\n    Nightwatch.start();\n  });\n\n  it('page object customCommand with selector', function(done) {\n    nocks\n      .elementFound('#signupSection')\n      .elementFound('#getStarted')\n      .elementFound('#helpBtn')\n      .elementIdNotFound(0, '#helpBtn', 'xpath')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '0'}]);\n\n    const page = Nightwatch.api().page.simplePageObj();\n    page.customCommandWithSelector('@loginAsString', function(result) {\n      assert.strictEqual(result.name, 'loginAsString');\n      assert.strictEqual(result.selector, '#weblogin');\n      assert.strictEqual(result.locateStrategy, 'css selector');\n    });\n\n    Nightwatch.start(function() {\n      done();\n    });\n  });\n\n  it('customCommand with section element selector', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementFound('#getStarted')\n      .elementFound('#helpBtn')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '10'}])\n      .clearValue('10');\n\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section.customClearValue('@help', function(selector, result) {\n      assert.deepStrictEqual(selector, {\n        WebdriverElementId: '10',\n        locateStrategy: 'css selector',\n        name: 'help',\n        response: {\n          status: 0,\n          value: {ELEMENT: '10'}\n        },\n        selector: '#helpBtn'\n      });\n\n      assert.deepStrictEqual(result, {\n        status: 0,\n        value: null\n      });\n    });\n\n    Nightwatch.start(done);\n  });\n\n  it('page object element command with custom message and no args', function(done) {\n    nocks.elementsFound('#weblogin');\n\n    const page = Nightwatch.api().page.simplePageObj();\n    page.waitForElementPresent('@loginAsString', 'element found');\n\n    const client = Nightwatch.client();\n    client.queue.tree.once('asynctree:finished', function(tree) {\n      const command = tree.currentNode.childNodes[0];\n      try {\n        strictEqual(command.args.length, 2);\n        const element = command.args[0];\n        strictEqual(element.name, 'loginAsString');\n        strictEqual(command.args[1], 'element found');\n        done();\n      } catch (e) {\n        done(e);\n      }\n    });\n\n    Nightwatch.start();\n  });\n\n  it('page object customCommand with selector called on section', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementFound('#getStarted')\n      .elementFound('#helpBtn')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '0'}]);\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section\n      .customCommandWithSelector('@help', function(result) {\n        assert.deepStrictEqual(result, {\n          selector: '#helpBtn',\n          WebdriverElementId: '0',\n          locateStrategy: 'css selector',\n          name: 'help',\n          response: {status: 0, value: {ELEMENT: '0'}}\n        });\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('page object customCommand without selector called on section', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementFound('#getStarted')\n      .elementFound('#helpBtn')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '0'}]);\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section\n      .customCommandWithSelector('test message', function(result) {\n        assert.strictEqual(result, 'test message');\n      });\n\n    Nightwatch.start(done);\n  });\n\n  it('page object customAssertion with selector', function(done) {\n    nocks\n      .elementFound('#signupSection')\n      .elementFound('#getStarted')\n      .elementFound('#helpBtn')\n      .elementIdNotFound(0, '#helpBtn', 'xpath')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '0'}]);\n\n    let page = Nightwatch.api().page.simplePageObj();\n\n    page\n      .assert.customAssertionWithSelector('@loginAsString', 0, function(result, assertion) {\n        try {\n          strictEqual(this.opts.rescheduleInterval, 50);\n          strictEqual(this.opts.timeout, 100);\n          strictEqual(result.passed, true);\n          strictEqual(assertion.element.selector, '#weblogin');\n          strictEqual(assertion.element.locateStrategy, 'css selector');\n          strictEqual(assertion.element.name, 'loginAsString');\n\n        } catch (err) {\n          done(err);\n        }\n      })\n      .assert.customAssertionWithSelector('@loginAsString', 1, function(result, assertion) {\n        try {\n          assert.strictEqual(result.passed, false);\n          assert.ok(result.err instanceof Error);\n          assert.ok(result.err.message.includes('in 100ms'));\n          strictEqual(assertion.rescheduleInterval, 50);\n          strictEqual(assertion.retryAssertionTimeout, 100);\n          strictEqual(assertion.element.selector, '#weblogin');\n          strictEqual(assertion.element.locateStrategy, 'css selector');\n          strictEqual(assertion.element.name, 'loginAsString');\n          done();\n        } catch (err) {\n          done(err);\n        }\n      });\n\n    Nightwatch.start();\n  });\n\n  it('page object customAssertion with selector called on section', function(done) {\n    nocks\n      .elementsFound('#signupSection')\n      .elementFound('#getStarted')\n      .elementFound('#helpBtn')\n      .elementsId('0', '#helpBtn', [{ELEMENT: '0'}]);\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section.assert.customAssertionWithSelector('@help', 0, function(result, assertion) {\n      try {\n        strictEqual(result.passed, true);\n        assert.deepStrictEqual(assertion.element, {\n          selector: '#helpBtn',\n          WebdriverElementId: '0',\n          locateStrategy: 'css selector',\n          name: 'help',\n          response: {\n            status: 0, value: {ELEMENT: '0'}\n          }\n        });\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n\n    Nightwatch.start();\n  });\n\n  it('page object customAssertion with indexed element called on section', function(done) {\n    nocks\n      .elementsFound('#signupSection') // page.section\n      .elementsId(0, '#helpBtn', [{ELEMENT: '1'}, {ELEMENT: '2'}])\n      .elementId(0, '#helpBtn', null, {ELEMENT: '1'});\n\n    let page = Nightwatch.api().page.simplePageObj();\n    let section = page.section.signUp;\n\n    section.assert.customAssertionWithSelector({selector: '@help', index: 1}, 0, function(result, assertion) {\n      try {\n        strictEqual(result.passed, true);\n        assert.deepStrictEqual(assertion.element, {\n          selector: '#helpBtn',\n          WebdriverElementId: '2',\n          locateStrategy: 'css selector',\n          name: 'help',\n          index: 1,\n          response: {status: 0, value: {ELEMENT: '2'}}\n        });\n        done();\n      } catch (err) {\n        done(err);\n      }\n    });\n\n    Nightwatch.start();\n  });\n\n  it('nested folder page object is loaded properly', function() {\n    let fooPage = Nightwatch.api().page.api.method.foo();\n    let fooSection = fooPage.section.foo;\n    strictEqual(fooSection.name, 'foo');\n\n    let barPage = Nightwatch.api().page.api.method.bar();\n    let barSection = barPage.section.bar;\n    strictEqual(barSection.name, 'bar');\n  });\n\n});\n"
  },
  {
    "path": "test/src/element/testProtocolElementSelectors.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst nocks = require('../../lib/nockselements.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test protocol element selectors', function() {\n  before(function(done) {\n    nocks.enable();\n    Nightwatch.startMockServer(done);\n  });\n\n  after(function(done) {\n    nocks.disable();\n    Nightwatch.stop(done);\n  });\n\n  beforeEach(function () {\n    nocks.cleanAll();\n\n    return Nightwatch.initAsync({\n      page_objects_path: [path.join(__dirname, '../../extra/pageobjects/pages')],\n      globals: {\n        abortOnAssertionFailure: true\n      },\n      backwards_compatibility_mode: true,\n      output: false,\n      silent: false\n    });\n  });\n\n  it('protocol.element(using, {selector})', function () {\n    nocks\n      .elementFound()\n      .elementNotFound();\n\n    Nightwatch.api()\n      .element('css selector', '#nock', function callback(result) {\n        assert.strictEqual(result.value.ELEMENT, '0');\n      })\n      .element('css selector', '#nock-none', function callback(result) {\n        assert.strictEqual(result.status, -1);\n      })\n      .element('css selector', {selector: '#nock'}, function callback(result) {\n        assert.strictEqual(result.value.ELEMENT, '0');\n      })\n      .element('css selector', {selector: '#nock-none'}, function callback(result) {\n        assert.strictEqual(result.status, -1);\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('protocol.element(using, null)', async function () {\n    Nightwatch.api().element('css selector', null);\n\n    let thrown;\n\n    try {\n      await Nightwatch.start();\n    } catch (err) {\n      thrown = err;\n    }\n\n    assert.ok(thrown instanceof Error);\n    assert.ok(thrown.message.includes('Invalid selector value specified'));\n  });\n\n  it('protocol.element(using, {})', async function () {\n    Nightwatch.api().element('css selector', {});\n\n    let thrown;\n\n    try {\n      await Nightwatch.start();\n    } catch (err) {\n      thrown = err;\n    }\n\n    assert.ok(thrown instanceof Error);\n    assert.ok(thrown.message.includes('No selector property for selector object'));\n  });\n\n  it('protocol.element(using, {selector, locateStrategy})', function () {\n    nocks.elementFound();\n\n    Nightwatch.api()\n      .element('css selector', {selector: '#nock', locateStrategy: 'css selector'}, function callback(result) {\n        assert.strictEqual(result.value.ELEMENT, '0');\n      })\n      .element('xpath', {selector: '#nock', locateStrategy: 'css selector'}, function callback(result) {\n        assert.strictEqual(result.value.ELEMENT, '0');\n      })\n      .element('css selector', {selector: '#nock', locateStrategy: null}, function callback(result) {\n        assert.strictEqual(result.value.ELEMENT, '0');\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('protocol.element(using, {locateStrategy})', async function () {\n    Nightwatch.api().element('css selector', {locateStrategy: 'css selector'});\n\n    let thrown;\n\n    try {\n      await Nightwatch.start();\n    } catch (err) {\n      thrown = err;\n    }\n\n    assert.ok(thrown instanceof Error);\n    assert.ok(thrown.message.includes('No selector property for selector object'));\n  });\n\n  it('protocol.element(using, {locateStrategy=invalid})', async function () {\n    Nightwatch.api().element('css selector', {selector: '.nock', locateStrategy: 'unsupported'});\n\n    let thrown;\n\n    try {\n      await Nightwatch.start();\n    } catch (err) {\n      thrown = err;\n    }\n\n    assert.ok(thrown instanceof Error);\n    assert.ok(thrown.message.includes('Provided locating strategy \"unsupported\" is not supported'));\n  });\n\n  it('protocol.elements(using, {selector})', async function () {\n    nocks\n      .elementsFound()\n      .elementsNotFound();\n\n    Nightwatch.api()\n      .elements('css selector', '.nock', function callback(result) {\n        assert.strictEqual(result.value[0].ELEMENT, '0', 'Found elements for string selector');\n      })\n      .elements('css selector', '.nock-none', function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.strictEqual(result.value.length, 0);\n      })\n      .elements('css selector', {selector: '.nock'}, function callback(result) {\n        assert.strictEqual(result.value[0].ELEMENT, '0');\n      })\n      .elements('css selector', {selector: '.nock-none'}, function callback(result) {\n        assert.strictEqual(result.status, 0);\n        assert.strictEqual(result.value.length, 0);\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('protocol.elements(using, null)', async function () {\n    Nightwatch.api().elements('css selector', null);\n\n    let thrown;\n\n    try {\n      await Nightwatch.start();\n    } catch (err) {\n      thrown = err;\n    }\n\n    assert.ok(thrown instanceof Error);\n    assert.ok(thrown.message.includes('Invalid selector value specified'));\n  });\n\n  it('protocol.elements(using, {})', async function () {\n    Nightwatch.api().elements('css selector', {});\n\n    let thrown;\n\n    try {\n      await Nightwatch.start();\n    } catch (err) {\n      thrown = err;\n    }\n\n    assert.ok(thrown instanceof Error);\n    assert.ok(thrown.message.includes('No selector property for selector object'));\n  });\n\n  it('protocol.elements(using, {selector, locateStrategy})', function () {\n    nocks\n      .elementsFound()\n      .elementsByTag();\n\n    Nightwatch.api()\n      .elements('css selector', {selector: '.nock', locateStrategy: 'css selector'}, function callback(result) {\n        assert.strictEqual(result.value[0].ELEMENT, '0');\n      })\n      .elements('xpath', {selector: '.nock', locateStrategy: 'css selector'}, function callback(result) {\n        assert.strictEqual(result.value[0].ELEMENT, '0');\n      })\n      .elements('xpath', {selector: 'nock', locateStrategy: 'css selector'}, function callback(result) {\n        assert.strictEqual(result.value[0].ELEMENT, '0');\n      })\n      .elements('css selector', {selector: '.nock', locateStrategy: null}, function callback(result) {\n        assert.strictEqual(result.value[0].ELEMENT, '0');\n      });\n\n    return Nightwatch.start();\n  });\n\n  it('protocol.elements(using, {locateStrategy})', async function () {\n    Nightwatch.api().elements('css selector', {locateStrategy: 'css selector'});\n\n    let thrown;\n\n    try {\n      await Nightwatch.start();\n    } catch (err) {\n      thrown = err;\n    }\n\n    assert.ok(thrown instanceof Error);\n    assert.ok(thrown.message.includes('No selector property for selector object'));\n  });\n\n  it('protocol.elements(using, {locateStrategy=invalid})', async function () {\n    Nightwatch.api().elements('css selector', {selector: '.nock', locateStrategy: 'unsupported'});\n\n    let thrown;\n\n    try {\n      await Nightwatch.start();\n    } catch (err) {\n      thrown = err;\n    }\n\n    assert.ok(thrown instanceof Error);\n    assert.ok(thrown.message.includes('Provided locating strategy \"unsupported\" is not supported'));\n  });\n\n});\n"
  },
  {
    "path": "test/src/globals.js",
    "content": "describe('tests', function() {\n  this.timeout(60000);\n});"
  },
  {
    "path": "test/src/index/testDefaultPathPrefixOption.js",
    "content": "const assert = require('assert');\nconst MockServer = require('../../lib/mockserver.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\nconst common = require('../../common.js');\nconst HttpRequest = common.require('http/request.js');\n\ndescribe('test defaultPathPrefix', function () {\n  before(function (done) {\n    this.server = MockServer.init();\n    this.server.on('listening', function () {\n      done();\n    });\n  });\n\n  after(function (done) {\n    Nightwatch.createClient({\n      default_path_prefix: '/wd/hub'\n    });\n    HttpRequest.globalSettings = {};\n\n    this.server.close(function () {\n      done();\n    });\n  });\n\n  it('testDefaultPathPrefix', function () {\n    Nightwatch.createClient({\n      selenium: {\n        start_process: true\n      }\n    });\n\n    var request = new HttpRequest({\n      host: '127.0.0.1',\n      path: '/test'\n    });\n\n    assert.strictEqual(request.defaultPathPrefix, '/wd/hub');\n  });\n\n  it('testSetDefaultPathPrefixOption', function () {\n    Nightwatch.createClient({\n      webdriver: {\n        default_path_prefix: '/test'\n      }\n    });\n\n    let request = new HttpRequest({\n      host: '127.0.0.1',\n      path: '/test',\n      port: 10195\n    });\n\n    assert.strictEqual(request.defaultPathPrefix, '');\n  });\n\n  it('test set defaultPathPrefix option when already set', function () {\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub'\n    };\n\n    Nightwatch.createClient({\n      default_path_prefix: '/test'\n    });\n\n    let request = new HttpRequest({\n      host: '127.0.0.1',\n      path: '/test',\n      port: 10195\n    });\n\n    assert.strictEqual(request.defaultPathPrefix, '');\n  });\n\n  it('testSetDefaultPathPrefixInvalidOption', function () {\n    HttpRequest.globalSettings = {\n      default_path: ''\n    };\n\n    Nightwatch.createClient({\n      webdriver: {\n        default_path_prefix: '/wd/hub'\n      }\n    });\n\n    let eq = assert.strictEqual;\n    let request = new HttpRequest({\n      host: '127.0.0.1',\n      path: '/session',\n      port: 10195\n    });\n\n    eq(request.defaultPathPrefix, '/wd/hub');\n  });\n\n  it('testSetDefaultPathPrefixEmptyOption', function () {\n    HttpRequest.globalSettings = {\n      default_path: ''\n    };\n\n    var request = new HttpRequest({\n      host: '127.0.0.1',\n      path: '/test',\n      port: 10195\n    });\n    assert.strictEqual(request.defaultPathPrefix, '');\n  });\n});\n\n"
  },
  {
    "path": "test/src/index/testMobileComponent.js",
    "content": "const assert = require('assert');\nconst common = require('../../common.js');\nconst NightwatchClient = common.require('index.js');\n\n\ndescribe('Mobile Component Testing in Android Emulator', function () {\n  it('test baseUrl - localhost', function() {\n    const client = NightwatchClient.client({\n      baseUrl: 'http://localhost:3000',\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        avd: 'nightwatch-android-11',\n        real_mobile: false\n      }\n    });\n\n    assert.strictEqual(client.api.baseUrl, 'http://10.0.2.2:3000');\n  });\n\n  it('test baseUrl - 127.0.0.1',  function(){\n    const client = NightwatchClient.client({\n      baseUrl: 'http://127.0.0.1:3000',\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        avd: 'nightwatch-android-11',\n        real_mobile: false\n      }\n    });\n\n    assert.strictEqual(client.api.baseUrl, 'http://10.0.2.2:3000');\n  });\n\n  it('test baseUrl - not defined',  function(){\n    const client = NightwatchClient.client({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        avd: 'nightwatch-android-11',\n        real_mobile: false\n      }\n    });\n\n    assert.strictEqual(client.api.baseUrl, null);\n  });\n\n  it('test baseUrl - non local',  function(){\n    const client = NightwatchClient.client({\n      baseUrl: 'https://www.google.com/',\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        avd: 'nightwatch-android-11',\n        real_mobile: false\n      }\n    });\n\n    assert.strictEqual(client.api.baseUrl, 'https://www.google.com/');\n  });\n\n  it('test baseUrl - real mobile',  function(){\n    const client = NightwatchClient.client({\n      baseUrl: 'http://127.0.0.1:3000',\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        avd: 'nightwatch-android-11',\n        real_mobile: true\n      }\n    });\n\n    assert.strictEqual(client.api.baseUrl, 'http://127.0.0.1:3000');\n  });\n\n  it('test baseUrl - no mobile',  function(){\n    const client = NightwatchClient.client({\n      baseUrl: 'http://127.0.0.1:3000',\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        real_mobile: false\n      }\n    });\n\n    assert.strictEqual(client.api.baseUrl, 'http://127.0.0.1:3000');\n  });\n});\n"
  },
  {
    "path": "test/src/index/testNightwatchIndex.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst MockServer = require('../../lib/mockserver.js');\nconst common = require('../../common.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\n\ndescribe('test NightwatchIndex', function () {\n  beforeEach(function (done) {\n    this.server = MockServer.init();\n    this.server.on('listening', function () {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    this.server.close(function () {\n      done();\n    });\n  });\n\n  it('Test initialization', function (done) {\n    const client = Nightwatch.createClient({\n      silent: false,\n      output: false\n    });\n\n    client.on('nightwatch:session.create', function (data) {\n      assert.strictEqual(client.api.sessionId, '1352110219202', 'Testing if session ID was set correctly');\n      assert.strictEqual(client.api.capabilities.browserName, 'firefox');\n      done();\n    });\n\n    client.startSession().catch(err => done(err));\n  });\n\n  it('testChromeSessionWithRedirectStatus', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session',\n\n      postdata: {\n        capabilities: {firstMatch: [{}], alwaysMatch: {browserName: 'chrome', 'goog:chromeOptions': {}}}\n      },\n\n      responseHeaders: {\n        location: 'http://localhost:10195/wd/hub/session/1352110219202'\n      },\n      statusCode: 302,\n      method: 'POST'\n    }, true);\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202',\n      response: JSON.stringify({\n        status: 0,\n        sessionId: '1352110219202',\n        value: {browserName: 'chrome'},\n        state: null\n      }),\n      responseHeaders: {\n        statusCode: 201\n      },\n      method: 'GET'\n    }, true);\n\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      silent: false,\n      output: false\n    });\n\n    client.on('nightwatch:session.create', function (data) {\n      assert.strictEqual(data.sessionId, '1352110219202');\n      assert.strictEqual(client.api.capabilities.browserName, 'chrome');\n      done();\n    });\n\n    client.startSession().catch(err => {\n      done(err);\n    });\n  });\n\n  it('testChromeSessionWithRelativeRedirectUrl', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session',\n      responseHeaders: {\n        location: '/wd/hub/session/1352110219203'\n      },\n      statusCode: 302,\n      method: 'POST'\n    }, true);\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219203',\n      response: JSON.stringify({\n        status: 0,\n        sessionId: '1352110219203',\n        value: {browserName: 'chrome'}\n      }),\n      responseHeaders: {\n        statusCode: 201\n      },\n      method: 'GET'\n    }, true);\n\n\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      silent: false,\n      output: false\n    });\n\n    client.on('nightwatch:session.create', function (data) {\n      assert.strictEqual(data.sessionId, '1352110219203');\n      assert.strictEqual(client.api.capabilities.browserName, 'chrome');\n      done();\n    });\n\n    client.startSession().catch(err => {\n      done(err);\n    });\n  });\n\n  it('test new Chrome session with wrong driver version error message', function () {\n    MockServer.addMock({\n      url: '/session',\n      response: {\n        sessionId: '8abea23aaa6bca9eb83f8f7c0f0cb17e',\n        status: 33,\n        value: {\n          message: 'session not created: This version of ChromeDriver only supports Chrome version 75',\n          error: [\n            '  (Driver info: chromedriver=75.0.3770.8 (681f24ea911fe754973dda2fdc6d2a2e159dd300-refs/branch-heads/3770@{#40}),platform=Mac OS X 10.14.4 x86_64)']\n        }\n      },\n      statusCode: 200,\n      method: 'POST'\n    }, true);\n\n    const client = Nightwatch.createClient({\n      selenium: {\n        start_process: false,\n        host: null\n      },\n      webdriver: {\n        start_process: false,\n        host: 'localhost',\n        port: '10195'\n      },\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      silent: false,\n      output: false\n    });\n\n    return client.startSession().catch(err => {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.message, 'An error occurred while creating a new ChromeDriver session: [SessionNotCreatedError] session not created: This version of ChromeDriver only supports Chrome version 75');\n    });\n  });\n\n  it('test createSession on Selenium Grid with Firefox', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session',\n      response: JSON.stringify({\n        platform: 'TEST',\n        value: {\n          sessionId: 'abc-123456',\n          capabilities: {\n            acceptInsecureCerts: true,\n            browserName: 'firefox',\n            browserVersion: '60.0.2'\n          }\n        }\n      }),\n      statusCode: 200,\n      method: 'POST'\n    }, true);\n\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'firefox',\n        platform: 'TEST',\n        'nightwatch:options': {\n          name: 'selenium-test'\n        }\n      },\n      selenium_host: 'localhost',\n      selenium_port: 10195,\n      silent: false,\n      output: false,\n      selenium: {\n        version2: false,\n        start_process: false\n      }\n    });\n\n    client.createSession()\n      .then(data => {\n        assert.strictEqual(data.sessionId, 'abc-123456');\n        assert.strictEqual(client.api.capabilities.browserName, 'firefox');\n        done();\n      })\n      .catch(err => done(err));\n  });\n\n  it('test session response with status success and no sessionId', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/session',\n      response: '{\"value\":{\"message\":\"Could not find device : iPhone 6\"}}',\n      statusCode: 200,\n      method: 'POST'\n    }, true);\n\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'safari'\n      },\n      silent: true,\n      output: false\n    });\n\n    client.startSession().catch(err => {\n      assert.ok(err instanceof Error);\n      assert.ok(err.message.includes('Could not find device : iPhone 6'));\n      done();\n    }).catch(err => done(err));\n  });\n\n  it('test create Transport for with browserName disabled', function() {\n    const Nightwatch = common.require('index.js');\n    const client = Nightwatch.client({\n      selenium: {\n        start_process: false\n      },\n      webdriver: {},\n      desiredCapabilities: {\n        browserName: null\n      },\n      selenium_host: 'remote.url'\n    });\n\n    assert.strictEqual(client.options.desiredCapabilities.browserName, null);\n  });\n\n\n  it('test runner API', function(done) {\n    const Nightwatch = common.require('index.js');\n    const CliRunner = common.require('runner/cli/cli.js');\n    const init = CliRunner.prototype.initTestSettings;\n    CliRunner.prototype.initTestSettings = function(opts = {}, baseSettings = null, argv = null, testEnv = null) {\n      assert.deepStrictEqual(argv, {\n        config: path.resolve('./test/extra/nightwatch.json'),\n        verbose: true,\n        reporter: ['junit', 'json', 'minimalJson', 'html'],\n        source: 'test.js',\n        _source: ['test.js']\n      });\n\n      init.call(this, opts, baseSettings, argv, testEnv);\n    };\n\n    Nightwatch.runner({\n      config: './test/extra/nightwatch.json',\n      verbose: true,\n      source: 'test.js'\n    }, function(err) {\n      CliRunner.prototype.initTestSettings = init;\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/index/testProgrammaticApis.js",
    "content": "const assert = require('assert');\nconst mockery = require('mockery');\nconst MockServer = require('../../lib/command-mocks.js');\nconst common = require('../../common.js');\nconst PluginLoader = common.require('api/_loaders/plugin.js');\nconst {Logger} = common.require('utils');\n\ndescribe('test programmatic apis', function () {\n  // [ '-vv', '--port=62625' ]\n  function getPortFromArg(args) {\n    const argItem = args.find(item => {\n      return /^--port=\\d+$/.test(item);\n    });\n\n    if (argItem) {\n      return Number(argItem.replace('--port=', ''));\n    }\n\n    return null;\n  }\n\n  beforeEach((done) => {\n    delete global.browser;\n\n    MockServer.start(done);\n    mockery.registerMock('@nightwatch/nightwatch-inspector', 'crxFile');\n    mockery.registerMock('./websocket-server', class {\n      initSocket() {};\n\n      closeSocket() {};\n    });\n  });\n  afterEach((done) => {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n\n    MockServer.stop(done);\n  });\n\n  it('test createClient() programmatic API defaults', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createFirefoxSession({});\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const client = Nightwatch.createClient({\n      headless: true,\n      silent: false,\n      output: false,\n      enable_global_apis: true\n    });\n\n    assert.ok(!!global.browser);\n    assert.ok(!!global.browser.page);\n\n    assert.deepStrictEqual(Object.keys(client), ['updateCapabilities', 'runGlobalBeforeHook', \n      'runGlobalAfterHook', 'launchBrowser', 'cleanup']);\n    assert.strictEqual(typeof client.launchBrowser, 'function');\n    assert.strictEqual(typeof client.settings, 'object');\n\n\n    const session = await client.launchBrowser();\n    assert.strictEqual(session.sessionId, '13521-10219-202');\n    assert.deepStrictEqual(session.capabilities, {\n      acceptInsecureCerts: false,\n      browserName: 'firefox',\n      browserVersion: '65.0.1'\n    });\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test createClient() programmatic API defaults with log_file_name', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createFirefoxSession({});\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const client = Nightwatch.createClient({\n      headless: true,\n      silent: false,\n      output: false,\n      enable_global_apis: true,\n      webdriver: {\n        log_path: '',\n        log_file_name: 'test-file'\n      }\n    });\n\n\n    assert.strictEqual(client.settings.webdriver.log_path, '');\n    assert.strictEqual(client.settings.webdriver.log_file_name, 'test-file');\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test createClient() programmatic API defaults parallel and remote server', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createFirefoxSession({});\n    MockServer.element({});\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const client = Nightwatch.createClient({\n      parallel: true,\n      headless: true\n    });\n\n    const session = await client.launchBrowser();\n\n    const {element} = Nightwatch;\n    const containerEl = element('#container');\n    const webElement = await containerEl.getWebElement();\n    const elementId = await webElement.getId();\n    assert.strictEqual(elementId, '5cc459b8-36a8-3042-8b4a-258883ea642b');\n\n    assert.strictEqual(session.sessionId, '13521-10219-202');\n    assert.strictEqual(session.options.webdriver.port, 10195);\n\n    assert.deepStrictEqual(session.capabilities, {\n      acceptInsecureCerts: false,\n      browserName: 'firefox',\n      browserVersion: '65.0.1'\n    });\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test createClient() programmatic API defaults with env', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createChromeSession({});\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        },\n        chrome_env: {\n          desiredCapabilities: {\n            browserName: 'chrome'\n          }\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const client = Nightwatch.createClient({\n      env: 'chrome_env',\n      headless: true,\n      disable_global_apis: true\n    });\n\n    assert.strictEqual(typeof global.browser, 'undefined');\n\n    const session = await client.launchBrowser();\n\n    assert.strictEqual(session.sessionId, '13521-10219-202');\n    assert.strictEqual(session.options.webdriver.port, 10195);\n\n    assert.deepStrictEqual(session.capabilities, {\n      acceptInsecureCerts: false,\n      browserName: 'chrome',\n      browserVersion: '90'\n    });\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test createClient() programmatic API not headless', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createFirefoxSession({});\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const client = Nightwatch.createClient({\n      headless: false\n    });\n\n    const session = await client.launchBrowser();\n\n    assert.strictEqual(session.sessionId, '1352110219202');\n    assert.deepStrictEqual(session.capabilities, {\n      browserName: 'firefox',\n      browserVersion: 'TEST_firefox'\n    });\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test createClient() programmatic API with external config', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createFirefoxSession({});\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    let customConfig;\n    CliRunner.prototype.loadConfig = function () {\n      customConfig = this.argv.config;\n\n      return defaultConfig;\n    };\n\n    const client = Nightwatch.createClient({\n      headless: true,\n      config: './custom-config.conf.js'\n    });\n\n    const session = await client.launchBrowser();\n\n    assert.strictEqual(customConfig, './custom-config.conf.js');\n    assert.strictEqual(session.sessionId, '13521-10219-202');\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test createClient() programmatic API with custom timeout', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createFirefoxSession({});\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const client = Nightwatch.createClient({\n      timeout: 500,\n      useAsync: false,\n      output: false,\n      silent: false,\n      headless: true,\n      output_folder: 'output',\n      globals: {\n        testGlobal: 'one'\n      }\n    });\n\n    const session = await client.launchBrowser();\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n    assert.strictEqual(session.options.always_async_commands, false);\n    assert.strictEqual(session.options.globals.retryAssertionTimeout, 500);\n    assert.strictEqual(session.options.globals.waitForConditionTimeout, 500);\n    assert.strictEqual(session.options.globals.testGlobal, 'one');\n    assert.strictEqual(session.options.silent, false);\n    assert.strictEqual(session.options.output_folder, 'output');\n    assert.strictEqual(session.sessionId, '13521-10219-202');\n  });\n\n  it('test createClient() programmatic API defaults with browserName', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createChromeSession({\n    });\n\n    MockServer.createFirefoxSession({});\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        },\n\n        chrome: {\n          desiredCapabilities: {\n            browserName: 'chrome'\n          }\n        },\n\n        firefox: {\n          desiredCapabilities: {\n            browserName: 'firefox'\n          }\n        },\n\n        safari: {\n          desiredCapabilities: {\n            browserName: 'chrome'\n          }\n        },\n\n        edge: {\n          desiredCapabilities: {\n            browserName: 'chrome'\n          }\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const clientChrome = Nightwatch.createClient({\n      browserName: 'chrome',\n      headless: true\n    });\n\n    const session = await clientChrome.launchBrowser();\n    assert.strictEqual(session.sessionId, '13521-10219-202');\n    assert.strictEqual(session.options.webdriver.port, 10195);\n\n    assert.deepStrictEqual(session.capabilities, {\n      acceptInsecureCerts: false,\n      browserName: 'chrome',\n      browserVersion: '90'\n    });\n\n    const clientFirefox = Nightwatch.createClient({\n      browserName: 'firefox',\n      headless: true\n    });\n\n    const sessionFirefox = await clientFirefox.launchBrowser();\n    assert.strictEqual(sessionFirefox.sessionId, '13521-10219-202');\n    assert.deepStrictEqual(sessionFirefox.capabilities, {\n      acceptInsecureCerts: false,\n      browserName: 'firefox',\n      browserVersion: '65.0.1'\n    });\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test createClient() programmatic API defaults parallel and local server', async function() {\n    const server_path = './bin/geckodriver';\n    const {constants, rmdirSync, readdirSync, lstatSync} = require('fs');\n    delete require.cache['fs'];\n\n    let serverPort;\n    mockery.enable({useCleanCache: true, warnOnUnregistered: false});\n    mockery.registerMock('fs', {\n      existsSync(exe) {\n        return !exe.includes('nightwatch-axe-verbose');\n      },\n      constants,\n      rmdirSync,\n      lstatSync,\n      readdirSync,\n      readFileSync() {\n        return true;\n      },\n      writeFile(filePath, output, cb) {\n        cb(null);\n      }\n    });\n\n    mockery.registerMock('../io/exec', {\n      exec: function (exe, opts) {\n        serverPort = getPortFromArg(opts.args);\n\n        return {\n          result() {\n            return Promise.resolve({\n              code: '0'\n            });\n          }\n        };\n      }\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Concurrency = common.require('runner/concurrency');\n    const Nightwatch = common.require('index.js');\n\n    Concurrency.isWorker = function() {\n      return true;\n    };\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      webdriver: {\n        port: 10195,\n        start_process: true,\n        server_path\n      },\n      selenium_host: 'localhost'\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const client = Nightwatch.createClient({\n      parallel: true\n    });\n\n    try {\n      await client.launchBrowser();\n    } catch (err) {\n    }\n\n    assert.strictEqual(typeof serverPort, 'number');\n    assert.ok(serverPort > 0);\n    assert.notStrictEqual(serverPort, 10195);\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test if process listener get disabled', async function() {\n    let processListenerCalled = false;\n    mockery.enable({useCleanCache: true, warnOnUnregistered: false});\n    mockery.registerMock('../process-listener.js', class {\n      constructor() {\n        processListenerCalled = true;\n      }\n\n      setTestRunner() {}\n    });\n\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const clientWithoutListner = Nightwatch.createClient({\n      timeout: 500,\n      useAsync: false,\n      output: false,\n      silent: false,\n      headless: true,\n      output_folder: 'output',\n      globals: {\n        testGlobal: 'one'\n      },\n      disable_process_listener: true\n    });\n\n    assert.ok(!processListenerCalled);\n\n    const client = Nightwatch.createClient({\n      timeout: 500,\n      useAsync: false,\n      output: false,\n      silent: false,\n      headless: true,\n      output_folder: 'output',\n      globals: {\n        testGlobal: 'one'\n      }\n    });\n\n    assert.ok(processListenerCalled);\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test runGlobalBeforeHook() programmatic API', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createFirefoxSession({});\n\n    let globalBeforeCalled = false;\n    let pluginBeforeCalled = false;\n    let pluginAfterCalled = false;\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost',\n\n      globals: {\n        before() {\n          globalBeforeCalled = true;\n        }\n      }\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const pluginLoader = PluginLoader.load;\n    PluginLoader.load = function(pluginName) {\n      return {\n        globals: {\n          before(settings) {\n            assert.deepEqual(settings.plugins, ['@nightwatch/mockedPlugin']);\n            pluginBeforeCalled = true;\n          },\n          after(settings) {\n            assert.deepEqual(settings.plugins, ['@nightwatch/mockedPlugin']);\n            pluginAfterCalled = true;\n          }\n        }\n      };\n    };\n\n    const client = Nightwatch.createClient({\n      headless: true,\n      silent: false,\n      output: false,\n      enable_global_apis: true,\n      plugins: ['@nightwatch/mockedPlugin']\n    });\n\n    await client.runGlobalBeforeHook();\n    await client.runGlobalAfterHook();\n\n    assert.ok(globalBeforeCalled);\n    assert.ok(pluginBeforeCalled);\n    assert.ok(pluginAfterCalled);\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n    PluginLoader.load = pluginLoader;\n  });\n\n  it('test runGlobalAfterHook() programmatic API', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createFirefoxSession({});\n\n    let globalAfterCalled = false;\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost',\n\n      globals: {\n        after() {\n          globalAfterCalled = true;\n        }\n      }\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const client = Nightwatch.createClient({\n      headless: true,\n      silent: false,\n      output: false,\n      enable_global_apis: true\n    });\n\n    await client.runGlobalAfterHook();\n\n    assert.ok(globalAfterCalled);\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test cleanup() programmatic API', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createFirefoxSession({});\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const client = Nightwatch.createClient({\n      headless: true,\n      silent: false,\n      output: false,\n      enable_global_apis: true\n    });\n\n    const session = await client.launchBrowser();\n\n    await client.cleanup();\n\n    const httpOutput = Logger.collectOutput();\n    const httpSectionOutput = Logger.collectTestSectionOutput();\n\n    assert.equal(httpOutput.length, 0);\n    assert.equal(httpSectionOutput.length, 0);\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('should test updateCapabilities() programmatic API with multiple nested caps', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createFirefoxSession({});\n  \n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n  \n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n  \n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n  \n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n  \n    const client = Nightwatch.createClient({\n      headless: true,\n      silent: false,\n      output: false,\n      enable_global_apis: true\n    });\n\n    client.updateCapabilities({\n      'testName': 'newCaps',\n      'options': {\n        'testCapabilitiesOne': 'capabilityOne'\n      }\n    });\n      \n    client.updateCapabilities({\n      'testName': 'updatedCaps',\n      'options': {\n        'testCapabilitiesTwo': 'capabilityTwo'\n      }\n    });\n  \n    const session = await client.launchBrowser();\n    assert.deepStrictEqual(session.desiredCapabilities, {\n      browserName: 'firefox',\n      testName: 'updatedCaps',\n      options: {\n        testCapabilitiesOne: 'capabilityOne',\n        testCapabilitiesTwo: 'capabilityTwo'\n      }\n    });\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n\n  it('test multiple calls to launchBrowser() on same client', async function() {\n    const CliRunner = common.require('runner/cli/cli.js');\n    const Nightwatch = common.require('index.js');\n    MockServer.createChromeSession({sessionId: '12345678'});\n    MockServer.createChromeSession({sessionId: '87654321'});\n\n    const defaultConfig = {\n      test_settings: {\n        default: {\n          launchUrl: 'http://localhost'\n        },\n\n        chrome: {\n          desiredCapabilities: {\n            browserName: 'chrome'\n          }\n        }\n      },\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost'\n    };\n\n    const createDefaultConfig = CliRunner.createDefaultConfig;\n    const loadConfig = CliRunner.prototype.loadConfig;\n\n    CliRunner.createDefaultConfig = function(destFileName) {\n      return defaultConfig;\n    };\n\n    CliRunner.prototype.loadConfig = function () {\n      return defaultConfig;\n    };\n\n    const clientChrome = Nightwatch.createClient({\n      browserName: 'chrome',\n      headless: true\n    });\n\n    const session = await clientChrome.launchBrowser();\n\n    assert.strictEqual(session.sessionId, '12345678');\n    assert.strictEqual(session.options.webdriver.port, 10195);\n    assert.deepStrictEqual(session.capabilities, {\n      acceptInsecureCerts: false,\n      browserName: 'chrome',\n      browserVersion: '90'\n    });\n\n    await session.end();\n    assert.strictEqual(session.sessionId, null);\n\n    let launchBrowserError;\n    try {\n      await clientChrome.launchBrowser();\n    } catch (err) {\n      launchBrowserError = err;\n    }\n    assert.notStrictEqual(launchBrowserError, undefined);\n    assert.strictEqual(launchBrowserError.message.includes('Error while loading the API commands'), true);\n\n    const session2 = await clientChrome.launchBrowser({loadNightwatchApis: false});\n\n    assert.strictEqual(session2.sessionId, '87654321');\n    assert.strictEqual(session2.options.webdriver.port, 10195);\n    assert.deepStrictEqual(session2.capabilities, {\n      acceptInsecureCerts: false,\n      browserName: 'chrome',\n      browserVersion: '90'\n    });\n\n    await session2.quit();\n    // TODO: calling `.quit()` does not clear the sessionId\n    assert.notStrictEqual(session2.sessionId, null);\n\n    CliRunner.createDefaultConfig = createDefaultConfig;\n    CliRunner.prototype.loadConfig = loadConfig;\n  });\n});\n"
  },
  {
    "path": "test/src/index/testRequest.js",
    "content": "const nock = require('nock');\nconst assert = require('assert');\nconst mockery = require('mockery');\nconst fs = require('fs');\nconst path = require('path');\n\nconst common = require('../../common.js');\nconst HttpRequest = common.require('http/request.js');\n\ndescribe('test HttpRequest', function() {\n\n  beforeEach(function (callback) {\n    try {\n      nock.activate();\n    } catch (err) {}\n\n    mockery.enable();\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444\n    };\n\n    nock('http://localhost:4444')\n      .post('/wd/hub/session')\n      .reply(200, {\n        status: 0,\n        sessionId: '123456-789',\n        value: {\n          browserName: 'firefox'\n        },\n        state: null\n      });\n    nock('http://localhost:4444')\n      .delete('/wd/hub/session')\n      .reply(200, {\n        status: 0,\n        sessionId: '123456-789'\n      });\n\n    nock('http://localhost:4444')\n      .get('/wd/hub/session')\n      .reply(200, {\n        status: 0,\n        sessionId: '123456-789'\n      });\n\n    nock('http://localhost:4444')\n      .put('/wd/hub/session')\n      .reply(200, {\n        status: 0,\n        sessionId: '123456-789'\n      });\n\n    nock('https://api-cloud.browserstack.com')\n      .post('/app-automate/upload')\n      .reply(200, {\n        app_url: 'bs://878bdf21505f0004ce',\n        custom_id: 'some_app'\n      });\n\n    callback();\n  });\n\n  afterEach(function () {\n    HttpRequest.resetHttpKeepAliveAgents();\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n  });\n\n  after(function() {\n    nock.restore();\n  });\n\n  it('testSendPostRequest', function(done) {\n    const options = {\n      path: '/session',\n      method: 'POST',\n      host: 'localhost',\n      port: 4444,\n      data: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        }\n      }\n    };\n\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).send();\n\n    const data = '{\"desiredCapabilities\":{\"browserName\":\"firefox\"}}';\n    assert.strictEqual(request.data, data);\n    assert.strictEqual(request.contentLength, data.length);\n\n    const opts = request.reqOptions;\n    assert.strictEqual(opts.path, '/wd/hub/session');\n    assert.strictEqual(opts.host, 'localhost');\n    assert.strictEqual(opts.port, 4444);\n    assert.strictEqual(opts.method, 'POST');\n    assert.strictEqual(opts.headers['content-type'], 'application/json; charset=utf-8');\n    assert.strictEqual(opts.headers['content-length'], data.length);\n    assert.ok(opts.headers['User-Agent'].startsWith('nightwatch.js/'));\n  });\n\n  it('testSendPostRequestWithCredentials', function (done) {\n    const options = {\n      path: '/session',\n      method: 'POST',\n      port: 4444,\n      data: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        }\n      }\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444,\n      credentials: {\n        username: 'test',\n        key: 'test-key'\n      }\n    };\n\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).on('error', function(err) {\n      console.error(err);\n      done(new Error('Request Failed!'));\n    }).send();\n\n    try {\n      const authHeader = Buffer.from('test:test-key').toString('base64');\n      assert.strictEqual(request.httpRequest.getHeader('Authorization'), 'Basic ' + authHeader);\n    } catch (err) {\n      done(err);\n    }\n\n  });\n\n  it('testSendPostRequestWithProxy', function (done) {\n    function ProxyAgentMock(uri) {\n      this.proxy = uri;\n    }\n\n    mockery.registerMock('proxy-agent', ProxyAgentMock);\n\n    const options = {\n      path: '/session',\n      method: 'POST',\n      port: 4444,\n      data: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        }\n      }\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444,\n      proxy: 'http://localhost:8080'\n    };\n\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).send();\n\n    const opts = request.reqOptions;\n    assert.ok('agent' in opts);\n    assert.ok('proxy' in opts.agent);\n  });\n\n  it('testGetRequest', function (done) {\n    nock('http://localhost:4444')\n      .get('/wd/hub/123456/element')\n      .reply(200, {});\n\n    const options = {\n      path: '/:sessionId/element',\n      method: 'GET',\n      port: 4444,\n      sessionId: '123456'\n    };\n\n    const request = new HttpRequest(options);\n    assert.strictEqual(request.data, '');\n    request.on('success', function (result) {\n      done();\n    }).send();\n\n    assert.strictEqual(request.httpRequest.getHeader('Accept'), 'application/json');\n    assert.strictEqual(request.reqOptions.path, '/wd/hub/123456/element');\n  });\n\n  it('testErrorResponseLocalised', function (done) {\n    nock('http://localhost:4444')\n      .post('/wd/hub/error')\n      .reply(500, {\n        value: {\n          status: -1,\n          stackTrace: '{}',\n          localizedMessage: 'no such element',\n          message: 'no such element'\n        }\n      });\n\n    const options = {\n      host: 'localhost',\n      path: '/wd/hub/error',\n      method: 'POST',\n      port: 4444,\n      data: {}\n    };\n\n    const request = new HttpRequest(options);\n    request.on('complete', function (result, response) {\n      assert.strictEqual(result.value.status, -1);\n      done();\n    }).send();\n  });\n\n  it('test send post request with keep alive', function (done) {\n    const options = {\n      path: '/session',\n      method: 'POST',\n      port: 4444,\n      data: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        }\n      }\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444,\n      keep_alive: true\n    };\n\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).send();\n\n    const opts = request.reqOptions;\n    const http = require('http');\n    assert.ok(opts.agent instanceof http.Agent);\n    assert.ok('agent' in opts);\n  });\n\n  it('test send post request with keep alive extended', function (done) {\n    const options = {\n      path: '/session',\n      method: 'POST',\n      port: 4444,\n      data: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        }\n      }\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444,\n      keep_alive: {\n        keepAliveMsecs: 1000,\n        enabled: true\n      }\n    };\n\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).send();\n\n    const opts = request.reqOptions;\n    const http = require('http');\n    assert.ok(opts.agent instanceof http.Agent);\n    assert.strictEqual(opts.agent.keepAliveMsecs, 1000);\n    assert.ok('agent' in opts);\n  });\n\n  it('keep alive uses single instance of agent across requests',  function() {\n    const options = {\n      path: '/session',\n      method: 'POST',\n      port: 4444,\n      data: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        }\n      }\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444,\n      keep_alive: {\n        keepAliveMsecs: 1000,\n        enabled: true\n      }\n    };\n\n    const request = new HttpRequest(options);\n    const secondRequest = new HttpRequest(options);\n\n    const opts = request.reqOptions;\n    const http = require('http');\n    assert.ok(opts.agent instanceof http.Agent);\n    assert.strictEqual(opts.agent.keepAliveMsecs, 1000);\n    assert.ok('agent' in opts);\n    assert.strictEqual(secondRequest.reqOptions.agent, opts.agent);\n  });\n\n  it('keep alive user agent changes when request protocol changes',  function() {\n    const optionsHttp = {\n      path: '/session',\n      method: 'POST',\n      port: 4444,\n      data: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        }\n      }\n    };\n\n    const optionsHttps = {\n      path: '/session',\n      method: 'POST',\n      port: 443,\n      data: {\n        desiredCapabilities: {\n          browserName: 'chrome'\n        }\n      }\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444,\n      keep_alive: {\n        keepAliveMsecs: 1000,\n        enabled: true\n      }\n    };\n\n    const httpRequest = new HttpRequest(optionsHttp);\n    const secondHttpRequest = new HttpRequest(optionsHttp);\n    const httpsRequest = new HttpRequest(optionsHttps);\n    const secondHttpsRequest = new HttpRequest(optionsHttps);\n    const thirdHttpRequest = new HttpRequest(optionsHttp);\n\n    const optsHttp = httpRequest.reqOptions;\n    assert.ok('agent' in optsHttp);\n    assert.ok(optsHttp.agent.protocol === 'http:');\n    assert.strictEqual(optsHttp.agent.keepAliveMsecs, 1000);\n\n    // first and second HTTP requests should share the same agent\n    assert.strictEqual(secondHttpRequest.reqOptions.agent, optsHttp.agent);\n\n    const optsHttps = httpsRequest.reqOptions;\n    assert.ok('agent' in optsHttps);\n    assert.ok(optsHttps.agent.protocol === 'https:');\n    // HTTPS agent should be different from HTTP agent\n    assert.notStrictEqual(optsHttps.agent, optsHttp.agent);\n\n    // first and second HTTPS requests should share the same agent\n    assert.strictEqual(secondHttpsRequest.reqOptions.agent, optsHttps.agent);\n    assert.notStrictEqual(secondHttpsRequest.reqOptions.agent, optsHttp.agent);\n\n    // while making HTTP request again after HTTPS request, it does\n    // not re-use the old HTTP agent (probably it should?)\n    assert.notStrictEqual(thirdHttpRequest.reqOptions.agent, optsHttp.agent);\n    assert.ok('agent' in thirdHttpRequest.reqOptions);\n    assert.ok(thirdHttpRequest.reqOptions.agent.protocol === 'http:');\n  });\n\n  it('test send post request with keep alive extended - disabled', function (done) {\n    const options = {\n      path: '/session',\n      method: 'POST',\n      port: 4444,\n      data: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        }\n      }\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444,\n      keep_alive: {\n        keepAliveMsecs: 1000,\n        enabled: false\n      }\n    };\n\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).send();\n\n    const opts = request.reqOptions;\n    assert.strictEqual(typeof opts.agent, 'undefined');\n  });\n\n  it('send POST request with empty data object', function(done){\n    const options = {\n      path: '/session',\n      method: 'POST',\n      port: 4444,\n      data: {}\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444\n    };\n\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).send();\n\n    assert.strictEqual(request.data, '{}');\n    assert.deepStrictEqual(request.params, {});\n  });\n\n  it('send DELETE request with data', function(done){\n    const options = {\n      path: '/session',\n      method: 'DELETE',\n      port: 4444,\n      data: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        }\n      }\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444\n    };\n\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).send();\n\n    assert.strictEqual(request.data, '');\n    assert.strictEqual(request.params, '');\n    \n  });\n\n\n  it('send GET request with data', function(done){\n    const options = {\n      path: '/session',\n      method: 'GET',\n      port: 4444,\n      data: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        }\n      }\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444\n    };\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).send();\n\n    assert.strictEqual(request.data, '');\n    assert.strictEqual(request.params, '');\n    \n  });\n\n\n  it('send PUT request with data', function(done){\n    const options = {\n      path: '/session',\n      method: 'PUT',\n      port: 4444,\n      data: {}\n    };\n\n    HttpRequest.globalSettings = {\n      default_path: '/wd/hub',\n      port: 4444\n    };\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).send();\n\n    assert.strictEqual(request.data, '{}');\n    assert.deepStrictEqual(request.params, {});\n    \n  });\n\n  it('send POST request with multi-part form data', function(done) {\n    mockery.registerMock('fs', {\n      readFileSync() {\n        return Buffer.from('app-data');\n      }\n    });\n\n    const options = {\n      method: 'POST',\n      url: 'https://api-cloud.browserstack.com/app-automate/upload',\n      use_ssl: true,\n      port: 443,\n      multiPartFormData: {\n        file: {\n          filePath: 'some/path/app.apk'\n        },\n        custom_id: {\n          data: 'some_app'\n        }\n      }\n    };\n\n    const request = new HttpRequest(options);\n    request.on('success', function () {\n      done();\n    }).send();\n\n    const boundary = request.formBoundary;\n    const data = `\\r\\n--${boundary}\\r\\nContent-Disposition: form-data; name=\"file\"; filename=\"app.apk\"\\r\\n\\r\\napp-data` +\n      `\\r\\n--${boundary}\\r\\nContent-Disposition: form-data; name=\"custom_id\"\\r\\n\\r\\nsome_app` +\n      `\\r\\n--${boundary}--`;\n    const bufferData = Buffer.from(data);\n\n    assert.deepStrictEqual(request.data, bufferData);\n    assert.strictEqual(request.contentLength, bufferData.length);\n    assert.strictEqual(request.use_ssl, true);\n\n    const opts = request.reqOptions;\n    assert.strictEqual(opts.path, '/app-automate/upload');\n    assert.strictEqual(opts.host, 'api-cloud.browserstack.com');\n    assert.strictEqual(opts.port, 443);\n    assert.strictEqual(opts.method, 'POST');\n    assert.strictEqual(opts.headers['content-type'], `multipart/form-data; boundary=${boundary}`);\n    assert.strictEqual(opts.headers['content-length'], bufferData.length);\n    assert.ok(opts.headers['User-Agent'].startsWith('nightwatch.js/'));\n  });\n});\n"
  },
  {
    "path": "test/src/index/testRequestTimeout.js",
    "content": "const common = require('../../common.js');\nconst HttpRequest = common.require('http/request.js');\nconst MockServer  = require('../../lib/mockserver.js');\nconst assert = require('assert');\n\ndescribe('test HttpRequestTimeout', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', function() {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('testRequestTimeout', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/123456/element',\n      response: '',\n      method: 'GET',\n      socketDelay: 400\n    }, true);\n\n    const options = {\n      path: '/:sessionId/element',\n      method: 'GET',\n      sessionId: '123456'\n    };\n\n    HttpRequest.globalSettings = {\n      timeout: 50,\n      default_path: '/wd/hub',\n      port: 10195\n    };\n\n    const request = new HttpRequest(options);\n\n    request.on('error', function (err) {\n      assert.strictEqual(err.code, 'ECONNRESET');\n      assert.ok(err instanceof Error);\n      done();\n    }).on('success', function(result, response) {\n      done(new Error('Request should have timed out.'));\n    }).send();\n\n  });\n\n  it('testRetryAttempts', function (done) {\n    MockServer.addMock({\n      url: '/wd/hub/10000000/element',\n      response: '',\n      method: 'GET',\n      socketDelay: 200\n    }, true).addMock({\n      url: '/wd/hub/10000000/element',\n      response: '',\n      method: 'GET'\n    }, true);\n\n    const options = {\n      path: '/:sessionId/element',\n      selenium_port: 10195,\n      method: 'GET',\n      sessionId: '10000000'\n    };\n\n    HttpRequest.globalSettings = {\n      host: 'localhost',\n      timeout: 50,\n      retry_attempts: 1,\n      default_path: '/wd/hub',\n      port: 10195,\n      credentials: {\n        username: '',\n        key: ''\n      }\n    };\n\n    const request = new HttpRequest(options);\n    assert.strictEqual(request.retryAttempts, 1);\n    assert.deepStrictEqual(request.httpOpts, {\n      host: 'localhost',\n      internal_server_error_retry_interval: 1000,\n      port: 10195,\n      default_path: '/wd/hub',\n      credentials: {\n        username: '',\n        key: ''\n      },\n      use_ssl: false,\n      proxy: null,\n      timeout: 50,\n      retry_attempts: 1\n    });\n\n    request\n      .on('error', function(err) {\n        assert.strictEqual(request.retryCount, 1);\n        assert.ok(err instanceof Error);\n        assert.strictEqual(err.code, 'ECONNRESET');\n      })\n      .on('success', function () {\n        assert.strictEqual(request.retryAttempts, 0);\n        assert.strictEqual(request.retryCount, 1);\n        done();\n      })\n      .send();\n  });\n});\n"
  },
  {
    "path": "test/src/index/testRunProtocolAction.js",
    "content": "const nock = require('nock');\nconst assert = require('assert');\n\nconst common = require('../../common.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\nconst HttpRequest = common.require('http/request.js');\nconst WebdriverProtocol = common.require('transport');\nconst SeleniumProtocol = common.require('transport/selenium-webdriver/selenium.js');\n\ndescribe('Trandport.runProtocolAction', function() {\n  const nightwatch = Nightwatch.createClientDefaults();\n\n  before(function() {\n    HttpRequest.globalSettings = {\n      default_path: '',\n      port: 4444,\n      host: 'localhost'\n    };\n  });\n\n  beforeEach(function () {\n    try {\n      nock.activate();\n    } catch (err) {\n    }\n  });\n\n  afterEach(function() {\n    nock.restore();\n  });\n\n  it('test runProtocolAction W3C Webdriver - socket hang up error', function() {\n    nock('http://localhost:4444')\n      .post('/session/123456/url')\n      .replyWithError({\n        message: 'socket hang up',\n        code: 'ECONNRESET'\n      });\n\n    const transport = new WebdriverProtocol(nightwatch);\n\n    return transport.runProtocolAction({\n      path: '/session/123456/url',\n      data: {\n        url: 'http://localhost'\n      },\n      method: 'POST'\n    }).then(result => {\n      throw new Error('An error should be thrown');\n    }).catch(err => {\n      assert.deepStrictEqual(err, {\n        status: -1,\n        code: 'ECONNRESET',\n        value: null,\n        errorStatus: '',\n        error: 'Error ECONNRESET: socket hang up',\n        httpStatusCode: null\n      });\n    });\n  });\n\n  it('test runProtocolAction W3C Webdriver - invalid session id error', function() {\n    nock('http://localhost:4444')\n      .post('/session/123456/url')\n      .reply(404, {\n        value: {\n          error: 'invalid session id',\n          message: 'No active session with ID',\n          stacktrace: ''\n        }\n      });\n\n    const transport = new WebdriverProtocol(nightwatch);\n\n    return transport.runProtocolAction({\n      path: '/session/123456/url',\n      data: {\n        url: 'http://localhost'\n      },\n      method: 'POST'\n    }).then(result => {\n      assert.deepStrictEqual(result, {\n        value: {\n          error: 'invalid session id',\n          message: 'No active session with ID',\n          stacktrace: ''\n        }\n      });\n    });\n  });\n\n\n  it('test runProtocolAction W3C Webdriver - command error', function() {\n    nock('http://localhost:4444')\n      .post('/session/123456/url')\n      .reply(400, {\n        value: {\n          error: 'unexpected alert open',\n          message: '',\n          stacktrace: '',\n          data: {\n            text: 'Message from window.alert'\n          }\n        }\n      });\n\n    const transport = new WebdriverProtocol(nightwatch);\n\n    return transport.runProtocolAction({\n      path: '/session/123456/url',\n      data: {\n        url: 'http://localhost'\n      },\n      method: 'POST'\n    }).then(result => {\n      assert.deepStrictEqual(result, {\n        value: {\n          error: 'unexpected alert open',\n          message: '',\n          stacktrace: '',\n          data: {text: 'Message from window.alert'}\n        }\n      });\n    });\n  });\n\n  it('test runProtocolAction SeleniumServer - command error', function() {\n    nock('http://localhost:4444')\n      .post('/session/123456/window/new')\n      .reply(500, {\n        value: {\n          stacktrace:\n              'org.openqa.selenium.UnsupportedCommandException: POST /session/84e7ae34-f100-fe4c-bfd1-75178b9bb522/window/new\\nBuild info: version: \\'3.141.59\\', revision: \\'e82be7d358\\', time: \\'2018-11-14T08:25:53\\'\\nSystem info: host: \\'MacBook-Pro-3.local\\', ip: \\'fe80:0:0:0:1cb3:9eb6:e69a:7912%en0\\', os.name: \\'Mac OS X\\', os.arch: \\'x86_64\\', os.version: \\'10.15.4\\', java.version: \\'1.8.0_161\\'\\nDriver info: driver.version: unknown\\n\\tat org.openqa.selenium.remote.http.AbstractHttpCommandCodec.decode(AbstractHttpCommandCodec.java:261)\\n\\tat org.openqa.selenium.remote.http.AbstractHttpCommandCodec.decode(AbstractHttpCommandCodec.java:117)\\n\\tat org.openqa.selenium.grid.session.remote.ProtocolConverter.handle(ProtocolConverter.java:74)\\n\\tat org.openqa.selenium.grid.session.remote.RemoteSession.execute(RemoteSession.java:129)\\n\\tat org.openqa.selenium.remote.server.WebDriverServlet.lambda$handle$0(WebDriverServlet.java:235)\\n\\tat java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)\\n\\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\\n\\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\\n\\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\\n\\tat java.lang.Thread.run(Thread.java:748)\\n',\n          stackTrace: [],\n          message:\n              'POST /session/84e7ae34-f100-fe4c-bfd1-75178b9bb522/window/new\\nBuild info: version: \\'3.141.59\\', revision: \\'e82be7d358\\', time: \\'2018-11-14T08:25:53\\'\\nSystem info: host: \\'MacBook-Pro-3.local\\', ip: \\'fe80:0:0:0:1cb3:9eb6:e69a:7912%en0\\', os.name: \\'Mac OS X\\', os.arch: \\'x86_64\\', os.version: \\'10.15.4\\', java.version: \\'1.8.0_161\\'\\nDriver info: driver.version: unknown',\n          error: 'unknown command'\n        },\n        status: 9\n      });\n\n    const transport = new SeleniumProtocol(nightwatch);\n\n    return transport.runProtocolAction({\n      path: '/session/123456/window/new',\n      data: {\n        url: 'http://localhost'\n      },\n      method: 'POST'\n    }).then(result => {\n      assert.deepStrictEqual(result, {\n        status: 9,\n        value: {\n          stacktrace: '',\n          stackTrace: [],\n          message:\n              'POST /session/84e7ae34-f100-fe4c-bfd1-75178b9bb522/window/new\\nBuild info: version: \\'3.141.59\\', revision: \\'e82be7d358\\', time: \\'2018-11-14T08:25:53\\'\\nSystem info: host: \\'MacBook-Pro-3.local\\', ip: \\'fe80:0:0:0:1cb3:9eb6:e69a:7912%en0\\', os.name: \\'Mac OS X\\', os.arch: \\'x86_64\\', os.version: \\'10.15.4\\', java.version: \\'1.8.0_161\\'\\nDriver info: driver.version: unknown',\n          error: 'unknown command'\n        }\n      });\n    });\n  });\n\n  it('test runProtocolAction SeleniumServer - socket hang up error', function() {\n    nock('http://localhost:4444')\n      .post('/session/123456/url')\n      .replyWithError({\n        message: 'socket hang up',\n        code: 'ECONNRESET'\n      });\n\n    const transport = new SeleniumProtocol(nightwatch);\n\n    return transport.runProtocolAction({\n      path: '/session/123456/url',\n      data: {\n        url: 'http://localhost'\n      },\n      method: 'POST'\n    }).then(result => {\n      throw new Error('An error should be thrown');\n    }).catch(err => {\n      assert.deepStrictEqual(err, {\n        status: -1,\n        code: 'ECONNRESET',\n        value: null,\n        errorStatus: '',\n        error: 'Error ECONNRESET: socket hang up',\n        httpStatusCode: null\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/index/testSettings.js",
    "content": "const assert = require('assert');\nconst common = require('../../common.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\nconst HttpRequest = common.require('http/request.js');\nconst Settings = common.require('settings/settings.js');\nconst eq = assert.strictEqual;\n\ndescribe('test Settings', function () {\n  it('testSetOptions', function () {\n    const client = Nightwatch.createClient({\n      use_xpath: true,\n      launch_url: '/home'\n    });\n\n    eq(client.locateStrategy, 'xpath');\n    eq(client.options.use_xpath, true);\n    eq(client.api.options.skip_testcases_on_fail, true);\n    eq(client.api.launchUrl, '/home');\n    eq(client.api.launch_url, '/home');\n  });\n\n  it('test set test_runner invalid value', function () {\n    assert.throws(function() {\n      const client = Nightwatch.createClient({\n        test_runner: null\n      });\n    }, /Error: Invalid \"test_runner\" settings specified; received: null/);\n  });\n\n  it('test set test_runner invalid value - function', function () {\n    assert.throws(function() {\n      const client = Nightwatch.createClient({\n        test_runner: function() {}\n      });\n    }, /Error: Invalid \"test_runner\" settings specified; received: function\\(\\) \\{\\}/);\n  });\n\n  it('test set test_runner string value', function () {\n\n    const client = Nightwatch.createClient({\n      test_runner: 'mocha'\n    });\n\n    assert.deepStrictEqual(client.settings.test_runner, {\n      options: {},\n      type: 'mocha'\n    });\n  });\n\n  it('testSetWebdriverOptionsDefaults', function () {\n    HttpRequest.globalSettings = {};\n    const client = Nightwatch.createClientDefaults();\n\n    eq(client.options.webdriver.host, 'localhost');\n    eq(client.options.webdriver.port, 4444);\n    eq(client.options.webdriver.ssl, false);\n\n    eq(client.api.options.screenshots.enabled, false);\n    eq(client.api.options.screenshots.path, '');\n\n    eq(client.options.start_session, true);\n    eq(client.options.end_session_on_fail, true);\n  });\n\n  it('testSetWebdriverOptions', function () {\n    const client = Nightwatch.createClient({\n      webdriver: {\n        host: '127.0.0.1',\n        ssl: false,\n        port: 10195,\n        timeout_options: {\n          timeout: 10000,\n          retry_attempts: 3\n        },\n        default_path_prefix: '',\n        username: 'test-user',\n        access_key: 'test-key'\n      }\n    });\n\n    const HttpRequest = common.require('http/request.js');\n    const request = new HttpRequest({});\n\n    eq(request.reqOptions.host, '127.0.0.1');\n    eq(request.reqOptions.port, 10195);\n    eq(request.hostname, '');\n    eq(request.defaultPathPrefix, '');\n  });\n\n  it('test to overwrite webdriver settings programmatically', function() {\n    const parsedSettings = Settings.parse({\n      webdriver: {\n        start_process: false,\n        server_path: './bin/geckodriver',\n        log_path: './logs'\n      }\n    }, {\n      screenshots: {\n        bla: false\n      },\n      test_settings: {\n        default: {\n          webdriver: {\n            start_process: true,\n            server_path: './bin/chromedriver',\n            log_path: './logs',\n            request_timeout_options: {\n              retry_attempts: 1\n            }\n          }\n        }\n      }\n    });\n\n    assert.strictEqual(parsedSettings.webdriver.start_process, false);\n    assert.strictEqual(parsedSettings.webdriver.server_path, './bin/geckodriver');\n    assert.strictEqual(parsedSettings.webdriver.log_path, './logs');\n    assert.deepStrictEqual(parsedSettings.webdriver.request_timeout_options, {\n      retry_attempts: 1\n    });\n  });\n\n  it('testSetSeleniumPort', function () {\n    const Nightwatch = common.require('index.js');\n    const Settings = common.require('settings/settings.js');\n\n    const settings = Settings.parse({\n      selenium: {\n        start_process: false\n      },\n      selenium_host: 'localhost.org',\n      selenium_port: 80\n    });\n\n    Nightwatch.client(settings, null);\n\n    const HttpRequest = common.require('http/request.js');\n    const request = new HttpRequest({});\n\n    eq(request.reqOptions.port, 80);\n  });\n\n  it('test create Transport for remote with Firefox', function() {\n    const Settings = common.require('settings/settings.js');\n\n    const settings = Settings.parse({\n      selenium: {\n        start_process: false\n      }\n    }, {\n      test_settings: {\n        default: {},\n        remote: {\n          selenium_host: 'localhost.org',\n          selenium_port: 8000\n        }\n      }\n    }, {}, 'remote');\n\n    assert.strictEqual(settings.webdriver.host, 'localhost.org');\n    assert.strictEqual(settings.webdriver.port, 8000);\n  });\n\n  it('testSetOptionsCredentials', function () {\n    const client = Nightwatch.createClient({\n      username: 'test-user',\n      accessKey: 'test-access-key'\n    });\n\n    eq(client.options.username, 'test-user');\n    eq(client.api.options.username, 'test-user');\n    eq(client.api.options.accessKey, 'test-access-key');\n    eq(client.options.accessKey, 'test-access-key');\n  });\n\n  it('testEnableFailFast', function () {\n    const client = Nightwatch.createClient({}, null, {\n      'fail-fast': true\n    });\n\n    eq(client.options.enable_fail_fast, true);\n  });\n\n  it('testSetOptionsScreenshots – path empty', function () {\n    const client = Nightwatch.createClient({\n      screenshots: {\n        enabled: true,\n        path: ''\n      },\n      log_screenshot_data: true\n    });\n\n    eq(client.api.options.log_screenshot_data, true);\n    eq(client.options.screenshots.on_error, true);\n    eq(client.settings.screenshots.on_error, true);\n    eq(client.settings.screenshots.path, '');\n  });\n\n  it('testSetOptionsScreenshots – path not empty', function () {\n    const client = Nightwatch.createClient({\n      screenshots: {\n        enabled: true,\n        path: '/tmp/'\n      },\n      log_screenshot_data: true\n    });\n\n    eq(client.api.options.log_screenshot_data, true);\n    eq(client.options.screenshots.on_error, true);\n    \n    if (process.platform === 'win32') {\n      assert.ok(client.settings.screenshots.path.endsWith('\\\\tmp'));\n    } else {\n      eq(client.settings.screenshots.path, '/tmp');\n    }\n  });\n\n\n  it('testSetOptionsScreenshotsOnError', function () {\n    const client = Nightwatch.createClient({\n      screenshots: {\n        enabled: true,\n        on_error: true,\n        path: ''\n      },\n      log_screenshot_data: true\n    });\n\n    eq(client.options.screenshots.on_error, true);\n  });\n\n  it('testSetOptionsScreenshotsThrows', function () {\n    const client = Nightwatch.createClient({\n      screenshots: true\n    });\n\n    eq(client.settings.screenshots.enabled, true);\n    eq(client.settings.screenshots.on_error, true);\n    eq(client.settings.screenshots.on_failure, true);\n    eq(client.settings.screenshots.path, '');\n    assert.ok(client.settings.screenshots.filename_format().startsWith('_FAILED_'));\n  });\n\n  it('testEndSessionOnFail', function () {\n    const client = Nightwatch.createClient({\n      end_session_on_fail: true\n    });\n\n    eq(client.options.end_session_on_fail, true);\n    client.endSessionOnFail(false);\n    eq(client.endSessionOnFail(), false);\n    eq(client.options.end_session_on_fail, false);\n  });\n\n  it('testSetRequestTimeoutOptions', function () {\n    const client = Nightwatch.createClient({\n      webdriver: {\n        timeout_options: {\n          timeout: 10000,\n          retry_attempts: 5\n        }\n      }\n    });\n\n    assert.deepStrictEqual(client.options.webdriver.timeout_options, {\n      timeout: 10000,\n      retry_attempts: 5\n    });\n\n\n    const HttpRequest = common.require('http/request.js');\n    const request = new HttpRequest({});\n\n    assert.strictEqual(request.httpOpts.timeout, 10000);\n    assert.strictEqual(request.retryAttempts, 5);\n  });\n\n  it('Test initialize with parallel cli argument', function () {\n    const settings = Settings.parse({\n      selenium_port: 10195,\n      silent: false,\n      output: false\n    }, {}, {\n      parallel: true\n    });\n\n    assert.strictEqual(settings.testWorkersEnabled, true);\n  });\n});\n\nxit('recursive extends in test_settings', function () {\n\n  const baseSettings = {\n    test_settings: {\n      browserstack: {\n        selenium: {\n          host: 'hub-cloud.browserstack.com',\n          port: 443\n        },\n        desiredCapabilities: {\n          'bstack:options': {\n            local: 'false'\n          }\n        },\n  \n        disable_error_log: true,\n        webdriver: {\n          keep_alive: true,\n          start_process: false\n        }\n      },\n      'browserstack.chrome': {\n        extends: 'browserstack',\n        desiredCapabilities: {\n          browserName: 'chrome',\n          chromeOptions: {\n            w3c: false\n          }\n        }\n      },\n      'browserstack.chrome_mac': {\n        extends: 'browserstack.chrome',\n        desiredCapabilities: {\n          os: 'OS X'\n        }\n      }\n    }\n  };\n  const expectedDesiredCapabilites = {\n    os: 'OS X',\n    browserName: 'chrome',\n    chromeOptions: {\n      w3c: false\n    },\n    'bstack:options': {\n      local: 'false'\n    }\n  };\n  const parsedSetting  = Settings.parse({}, baseSettings, {}, 'browserstack.chrome_mac');\n  assert.strictEqual(parsedSetting.selenium.host, 'hub-cloud.browserstack.com');\n  assert.strictEqual(parsedSetting.selenium.port, 443);\n  assert.deepStrictEqual(parsedSetting.desiredCapabilities, expectedDesiredCapabilites);\n  assert.deepStrictEqual(parsedSetting.desiredCapabilities.chromeOptions, {w3c: false});\n});\n"
  },
  {
    "path": "test/src/index/transport/testAppiumTransport.js",
    "content": "const assert = require('assert');\nconst common = require('../../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst Appium = common.require('transport/selenium-webdriver/appium.js');\n\n\ndescribe('AppiumTransport', function () {\n  it('test create Transport for Appium external',  function(){\n    const client = NightwatchClient.client({\n      selenium: {\n        start_process: false,\n        use_appium: true,\n        host: 'remote.host',\n        port: 443\n      },\n      webdriver: {\n        start_process: false\n      },\n      output: true,\n      silent: false,\n      desiredCapabilities: {\n        browserName: '',\n        platformName: 'iOS',\n        platformVersion: '15.5',\n        deviceName: 'iPhone 13'\n      }\n    });\n\n    assert.ok(client.transport instanceof Appium);\n    assert.strictEqual(client.settings.webdriver.host, 'remote.host');\n    assert.strictEqual(client.settings.webdriver.port, 443);\n    assert.strictEqual(client.settings.webdriver.ssl, true);\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n    assert.strictEqual(client.transport.desiredCapabilities.browserName, '');\n  });\n\n  it('test create Transport for Appium managed with Firefox',  function(){\n    const client = NightwatchClient.client({\n      selenium: {\n        start_process: true,\n        use_appium: true\n      },\n      webdriver: {\n        start_process: false\n      },\n      output: true,\n      silent: false,\n      desiredCapabilities: {\n        browserName: 'firefox',\n        platformName: 'Android'\n      }\n    });\n\n    assert.ok(client.transport instanceof Appium);\n    assert.strictEqual(client.settings.webdriver.host, 'localhost');\n    assert.strictEqual(client.settings.webdriver.port, 4723);\n    assert.strictEqual(client.settings.webdriver.ssl, false);\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n    assert.strictEqual(client.settings.webdriver.start_process, true);\n    assert.strictEqual(client.transport.desiredCapabilities.browserName, 'firefox');\n  });\n\n  it('test create Transport for Appium without use_appium and with browserName=null',  function(){\n    const client = NightwatchClient.client({\n      webdriver: {\n        start_process: false\n      },\n      selenium: {\n        start_process: true,\n        host: 'localhost',\n        port: 9999,\n        default_path_prefix: '',\n        '[_started]': true\n      },\n      output: true,\n      silent: false,\n      desiredCapabilities: {\n        browserName: null\n      }\n    });\n\n    assert.ok(client.transport instanceof Appium);\n    assert.strictEqual(client.settings.webdriver.host, 'localhost');\n    assert.strictEqual(client.settings.webdriver.port, 9999);\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '');\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n    assert.strictEqual(client.transport.desiredCapabilities.browserName, null);\n  });\n});\n"
  },
  {
    "path": "test/src/index/transport/testBrowserstackTransport.js",
    "content": "const assert = require('assert');\nconst nock = require('nock');\nconst common = require('../../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst SeleniumRemote = common.require('transport/selenium-webdriver/selenium.js');\nconst Automate = common.require('transport/selenium-webdriver/browserstack/automate.js');\nconst AppAutomate = common.require('transport/selenium-webdriver/browserstack/appAutomate.js');\nconst AutomateTurboScale = common.require('transport/selenium-webdriver/browserstack/automateTurboScale.js');\n\ndescribe('BrowserstackTransport', function () {\n  beforeEach(function() {\n    try {\n      nock.activate();\n      // eslint-disable-next-line no-empty\n    } catch (err) {}\n  });\n\n  afterEach(function() {\n    nock.cleanAll();\n    nock.restore();\n  });\n\n  it('test create Transport for Browserstack - empty credentials', function() {\n    assert.rejects(async function() {\n      const client = NightwatchClient.client({\n        webdriver: {\n          host: 'hub-cloud.browserstack.com',\n          port: 443\n        }\n      });\n\n      await client.transport.createSession({argv: undefined, moduleKey: ''});\n\n    }, /BrowserStack access key is not set\\. Verify that \"browserstack\\.key\" capability is set correctly or set BROWSERSTACK_KEY environment variable \\(\\.env files are supported\\)\\./);\n\n    assert.rejects(async function() {\n      const client = NightwatchClient.client({\n        webdriver: {\n          host: 'hub-cloud.browserstack.com',\n          port: 443\n        },\n        desiredCapabilities: {\n          'browserstack.key': 'test-access-key'\n        }\n      });\n\n      await client.transport.createSession({argv: undefined, moduleKey: ''});\n\n    }, /BrowserStack username is not set\\. Verify that \"browserstack\\.user\" capability is set correctly or set BROWSERSTACK_USER environment variable \\(\\.env files are supported\\)\\./);\n\n  });\n\n  it('test create Transport for Browserstack - env variable credentials', async function() {\n    process.env['USER'] = 'test-access-user';\n    process.env['KEY'] = 'test-access-key';\n\n    const client = NightwatchClient.client({\n      webdriver: {\n        host: 'hub-cloud.browserstack.com',\n        port: 443\n      },\n      desiredCapabilities: {\n        'browserstack.user': '${USER}',\n        'browserstack.key': '${KEY}'\n      }\n    });\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=0')\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'nightwatch-test-build',\n            hashed_id: '123-567-89'\n          }\n        },\n        {\n          automation_build: {\n            name: 'test-build'\n          }\n        }\n      ]);\n\n    const {transport} = client;\n    const result = await transport.createSession({argv: undefined, moduleKey: ''});\n    result.sessionId = '1234567';\n    client.emit('nightwatch:session.create', result);\n\n    assert.ok(transport instanceof SeleniumRemote);\n    assert.strictEqual(transport.username, 'test-access-user');\n    assert.strictEqual(transport.accessKey, 'test-access-key');\n\n    delete process.env['USER'];\n    delete process.env['KEY'];\n  });\n\n  it('test create Transport for Browserstack - Automate', async function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        host: 'hub-cloud.browserstack.com',\n        port: 443,\n        start_process: true\n      },\n      desiredCapabilities: {\n        'browserstack.user': 'test-access-user',\n        'browserstack.key': 'test-access-key',\n        browserName: 'chrome'\n      }\n    });\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=0')\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'nightwatch-test-build',\n            hashed_id: '123-567-89'\n          }\n        },\n        {\n          automation_build: {\n            name: 'test-build'\n          }\n        }\n      ]);\n\n    assert.ok(client.transport instanceof Automate);\n    assert.strictEqual(client.settings.webdriver.host, 'hub-cloud.browserstack.com');\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n    assert.strictEqual(client.settings.webdriver.ssl, true);\n\n    const {transport} = client;\n    assert.ok(transport instanceof SeleniumRemote);\n\n    let result = await transport.createSession({argv: undefined, moduleKey: ''});\n    result.sessionId = '1234567';\n    client.emit('nightwatch:session.create', result);\n\n    assert.strictEqual(transport.username, 'test-access-user');\n    assert.strictEqual(transport.accessKey, 'test-access-key');\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n\n    nock('https://api.browserstack.com')\n      .get('/automate/sessions/1234567.json')\n      .reply(200, {\n        automation_session: {status: 'done'}\n      });\n    nock('https://api.browserstack.com')\n      .put('/automate/sessions/1234567.json', {\n        status: 'passed',\n        reason: ''\n      })\n      .reply(200, {});\n\n    result = await transport.testSuiteFinished(false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(transport.sessionId, null);\n\n    assert.strictEqual(transport.buildId, '123-567-89');\n\n  });\n\n  it('test create Transport for Browserstack - Automate (port 4444)', async function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        host: 'hub-cloud.browserstack.com',\n        port: 4444,\n        start_process: true\n      },\n      desiredCapabilities: {\n        'browserstack.user': 'test-access-user',\n        'browserstack.key': 'test-access-key',\n        browserName: 'chrome'\n      }\n    });\n\n    nock('http://hub-cloud.browserstack.com:4444')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=0')\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'nightwatch-test-build',\n            hashed_id: '123-567-89'\n          }\n        },\n        {\n          automation_build: {\n            name: 'test-build'\n          }\n        }\n      ]);\n\n    assert.ok(client.transport instanceof Automate);\n    assert.strictEqual(client.settings.webdriver.host, 'hub-cloud.browserstack.com');\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n    assert.strictEqual(client.settings.webdriver.ssl, false);\n\n    const {transport} = client;\n    assert.ok(transport instanceof SeleniumRemote);\n\n    let result = await transport.createSession({argv: undefined, moduleKey: ''});\n    result.sessionId = '1234567';\n    client.emit('nightwatch:session.create', result);\n\n    assert.strictEqual(transport.username, 'test-access-user');\n    assert.strictEqual(transport.accessKey, 'test-access-key');\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n\n    let sessionNockCalled = 0;\n\n    nock('https://api.browserstack.com')\n      .get('/automate/sessions/1234567.json')\n      .reply(200, function () {\n        sessionNockCalled++;\n\n        return {automation_session: {status: 'done'}};\n      });\n    nock('https://api.browserstack.com')\n      .put('/automate/sessions/1234567.json', {\n        status: 'passed',\n        reason: ''\n      })\n      .reply(200, function () {\n        sessionNockCalled++;\n\n        return {};\n      });\n\n    result = await transport.testSuiteFinished(false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(transport.sessionId, null);\n\n    assert.strictEqual(transport.buildId, '123-567-89');\n    assert.strictEqual(sessionNockCalled, 2);\n  });\n\n  it('test create Transport for Browserstack - App Automate', async function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        host: 'hub-cloud.browserstack.com',\n        port: 443,\n        start_process: true\n      },\n      desiredCapabilities: {\n        'browserstack.user': 'test-access-user',\n        'browserstack.key': 'test-access-key',\n        browserName: ''\n      }\n    });\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/app-automate/builds.json?status=running&limit=20&offset=0')\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'nightwatch-test-build',\n            hashed_id: '123-567-89'\n          }\n        },\n        {\n          automation_build: {\n            name: 'test-build'\n          }\n        }\n      ]);\n\n    assert.ok(client.transport instanceof AppAutomate);\n    assert.strictEqual(client.settings.webdriver.host, 'hub-cloud.browserstack.com');\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n    assert.strictEqual(client.settings.webdriver.ssl, true);\n\n    const {transport} = client;\n    assert.ok(transport instanceof SeleniumRemote);\n\n    let result = await transport.createSession({argv: undefined, moduleKey: ''});\n    result.sessionId = '1234567';\n    client.emit('nightwatch:session.create', result);\n\n    assert.strictEqual(transport.username, 'test-access-user');\n    assert.strictEqual(transport.accessKey, 'test-access-key');\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n\n    nock('https://api.browserstack.com')\n      .get('/app-automate/sessions/1234567.json')\n      .reply(200, {\n        automation_session: {status: 'done'}\n      });\n    nock('https://api.browserstack.com')\n      .put('/app-automate/sessions/1234567.json', {\n        status: 'passed',\n        reason: ''\n      })\n      .reply(200, {});\n\n    result = await transport.testSuiteFinished(false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(transport.sessionId, null);\n\n    assert.strictEqual(transport.buildId, '123-567-89');\n  });\n\n  it('test create Transport for Browserstack - Automate TurboScale', async function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        host: 'hub-cloud.browserstack-ats.com',\n        port: 443,\n        start_process: true\n      },\n      desiredCapabilities: {\n        'browserstack.user': 'test-access-user',\n        'browserstack.key': 'test-access-key',\n        browserName: 'chrome'\n      }\n    });\n\n    nock('https://hub-cloud.browserstack-ats.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate-turboscale/v1/builds?status=running&limit=20&offset=0')\n      .reply(200, {\n        'builds': [\n          {\n            name: 'nightwatch-test-build',\n            hashed_id: '123-567-89'\n          },\n          {\n            name: 'test-build'\n          }\n        ]\n      });\n\n    assert.ok(client.transport instanceof AutomateTurboScale);\n    assert.strictEqual(client.settings.webdriver.host, 'hub-cloud.browserstack-ats.com');\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n    assert.strictEqual(client.settings.webdriver.ssl, true);\n\n    const {transport} = client;\n    assert.ok(transport instanceof SeleniumRemote);\n\n    let result = await transport.createSession({argv: undefined, moduleKey: ''});\n    assert.strictEqual(result.sessionId, '1352110219202');\n\n    client.emit('nightwatch:session.create', result);\n\n    assert.strictEqual(transport.username, 'test-access-user');\n    assert.strictEqual(transport.accessKey, 'test-access-key');\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n\n    let sessionNockCalled = 0;\n\n    nock('https://api.browserstack.com')\n      .get('/automate-turboscale/v1/sessions/1352110219202')\n      .reply(200, function(){\n        sessionNockCalled++;\n\n        return {status: 'done'};\n      });\n    nock('https://api.browserstack.com')\n      .patch('/automate-turboscale/v1/sessions/1352110219202', {\n        status: 'passed',\n        reason: ''\n      })\n      .reply(200, function(){\n        sessionNockCalled++;\n\n        return {};\n      });\n\n    result = await transport.testSuiteFinished(false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(transport.sessionId, null);\n\n    assert.strictEqual(sessionNockCalled, 2);\n    assert.strictEqual(transport.buildId, '123-567-89');\n  });\n\n  it('test create Transport for Browserstack with failures', async function() {\n    const client = NightwatchClient.client({\n      output: false,\n      silent: false,\n      webdriver: {\n        host: 'hub-cloud.browserstack.com',\n        port: 443,\n        start_process: true\n      },\n      desiredCapabilities: {\n        'browserstack.user': 'test-access-user',\n        'browserstack.key': 'test-access-key',\n        browserName: 'chrome'\n      }\n    });\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=0')\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'nightwatch-test-build',\n            hashed_id: '123-567-89'\n          }\n        },\n        {\n          automation_build: {\n            name: 'test-build'\n          }\n        }\n      ]);\n\n    const {transport} = client;\n    let result = await transport.createSession({argv: undefined, moduleKey: ''});\n    result.sessionId = '1234567';\n    client.emit('nightwatch:session.create', result);\n\n    return new Promise((resolve, reject) => {\n      setTimeout(async function() {\n        try {\n          nock('https://api.browserstack.com')\n            .get('/automate/sessions/1234567.json')\n            .reply(200, {\n              automation_session: {status: 'done'}\n            });\n          nock('https://api.browserstack.com')\n            .put('/automate/sessions/1234567.json', {\n              status: 'failed',\n              reason: 'NightwatchAssertError: Timed out while waiting for element <#james> to be present for 5000 milliseconds. - expected \"visible\" but got: \"not found\" (5400ms)'\n            })\n            .reply(200, {});\n\n          const error = new Error('Timed out while waiting for element <#james> to be present for 5000 milliseconds. - expected \"visible\" but got: \"not found\" (5400ms)');\n          error.name = 'NightwatchAssertError';\n\n          result = await transport.testSuiteFinished(error);\n\n          assert.strictEqual(result, true);\n          assert.strictEqual(transport.sessionId, null);\n          resolve();\n        } catch (err) {\n          reject(err);\n        }\n      }, 100);\n    });\n  });\n\n  it('test create Transport for Browserstack - Automate and Check the result in second page', async function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        host: 'hub-cloud.browserstack.com',\n        port: 443,\n        start_process: true\n      },\n      desiredCapabilities: {\n        'browserstack.user': 'test-access-user',\n        'browserstack.key': 'test-access-key',\n        browserName: 'chrome'\n      }\n    });\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=0')\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'nightwatch-test',\n            hashed_id: '123-56'\n          }\n        },\n        {\n          automation_build: {\n            name: 'test-build'\n          }\n        }\n      ]);\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=20')\n      .reply(200, [\n        {\n          automation_build: {\n            name: 'nightwatch-test-build',\n            hashed_id: '123-567-89'\n          }\n        },\n        {\n          automation_build: {\n            name: 'test-build'\n          }\n        }\n      ]);\n    assert.ok(client.transport instanceof Automate);\n    assert.strictEqual(client.settings.webdriver.host, 'hub-cloud.browserstack.com');\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n    assert.strictEqual(client.settings.webdriver.ssl, true);\n\n    const {transport} = client;\n    assert.ok(transport instanceof SeleniumRemote);\n\n    let result = await transport.createSession({argv: undefined, moduleKey: ''});\n    result.sessionId = '1234567';\n    client.emit('nightwatch:session.create', result);\n\n    assert.strictEqual(transport.username, 'test-access-user');\n    assert.strictEqual(transport.accessKey, 'test-access-key');\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n\n    nock('https://api.browserstack.com')\n      .get('/automate/sessions/1234567.json')\n      .reply(200, {\n        automation_session: {status: 'done'}\n      });\n    nock('https://api.browserstack.com')\n      .put('/automate/sessions/1234567.json', {\n        status: 'passed',\n        reason: ''\n      })\n      .reply(200, {});\n\n    result = await transport.testSuiteFinished(false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(transport.sessionId, null);\n\n    assert.strictEqual(transport.buildId, '123-567-89');\n\n  });\n\n  it('test create Transport for Browserstack - Automate and return undefined for empty array', async function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        host: 'hub-cloud.browserstack.com',\n        port: 443,\n        start_process: true\n      },\n      desiredCapabilities: {\n        'browserstack.user': 'test-access-user',\n        'browserstack.key': 'test-access-key',\n        browserName: 'chrome'\n      }\n    });\n    let buildsMockCalled = 0;\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=0')\n      .reply(200, function() {\n        buildsMockCalled++;\n\n        return [];\n      });\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running&limit=20&offset=20')\n      .reply(200, function() {\n        buildsMockCalled++;\n\n        return [];\n      });\n\n    assert.ok(client.transport instanceof Automate);\n    assert.strictEqual(client.settings.webdriver.host, 'hub-cloud.browserstack.com');\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n    assert.strictEqual(client.settings.webdriver.ssl, true);\n\n    const {transport} = client;\n    assert.ok(transport instanceof SeleniumRemote);\n\n    let result = await transport.createSession({argv: undefined, moduleKey: ''});\n    result.sessionId = '1234567';\n    client.emit('nightwatch:session.create', result);\n\n    assert.strictEqual(transport.username, 'test-access-user');\n    assert.strictEqual(transport.accessKey, 'test-access-key');\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n\n    nock('https://api.browserstack.com')\n      .get('/automate/sessions/1234567.json')\n      .reply(200, {\n        automation_session: {status: 'done'}\n      });\n    nock('https://api.browserstack.com')\n      .put('/automate/sessions/1234567.json', {\n        status: 'passed',\n        reason: ''\n      })\n      .reply(200, {});\n\n    result = await transport.testSuiteFinished(false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(transport.sessionId, null);\n\n    assert.strictEqual(buildsMockCalled, 1);\n    assert.strictEqual(transport.buildId, undefined);\n\n  });\n\n  it('test create Transport for Browserstack - Automate TurboScale And and Check the result in second page', async function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        host: 'hub-cloud.browserstack-ats.com',\n        port: 443,\n        start_process: true\n      },\n      desiredCapabilities: {\n        'browserstack.user': 'test-access-user',\n        'browserstack.key': 'test-access-key',\n        browserName: 'chrome'\n      }\n    });\n\n    nock('https://hub-cloud.browserstack-ats.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate-turboscale/v1/builds?status=running&limit=20&offset=0')\n      .reply(200, {\n        'builds': [\n          {\n            name: 'test',\n            hashed_id: '123-567-89'\n          },\n          {\n            name: 'test-build'\n          }\n        ]\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate-turboscale/v1/builds?status=running&limit=20&offset=20')\n      .reply(200, {\n        'builds': [\n          {\n            name: 'nightwatch-test-build',\n            hashed_id: '123-567-89'\n          },\n          {\n            name: 'test-build'\n          }\n        ]\n      });\n\n    assert.ok(client.transport instanceof AutomateTurboScale);\n    assert.strictEqual(client.settings.webdriver.host, 'hub-cloud.browserstack-ats.com');\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n    assert.strictEqual(client.settings.webdriver.ssl, true);\n\n    const {transport} = client;\n    assert.ok(transport instanceof SeleniumRemote);\n\n    let result = await transport.createSession({argv: undefined, moduleKey: ''});\n    assert.strictEqual(result.sessionId, '1352110219202');\n\n    client.emit('nightwatch:session.create', result);\n\n    assert.strictEqual(transport.username, 'test-access-user');\n    assert.strictEqual(transport.accessKey, 'test-access-key');\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n\n    let sessionNockCalled = 0;\n\n    nock('https://api.browserstack.com')\n      .get('/automate-turboscale/v1/sessions/1352110219202')\n      .reply(200, function(){\n        sessionNockCalled++;\n\n        return {status: 'done'};\n      });\n    nock('https://api.browserstack.com')\n      .patch('/automate-turboscale/v1/sessions/1352110219202', {\n        status: 'passed',\n        reason: ''\n      })\n      .reply(200, function(){\n        sessionNockCalled++;\n\n        return {};\n      });\n\n    result = await transport.testSuiteFinished(false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(transport.sessionId, null);\n\n    assert.strictEqual(sessionNockCalled, 2);\n    assert.strictEqual(transport.buildId, '123-567-89');\n  });\n\n  it('test create Transport for Browserstack - Automate TurboScale and return undefined for empty array', async function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        host: 'hub-cloud.browserstack-ats.com',\n        port: 443,\n        start_process: true\n      },\n      desiredCapabilities: {\n        'browserstack.user': 'test-access-user',\n        'browserstack.key': 'test-access-key',\n        browserName: 'chrome'\n      }\n    });\n    let buildsMockCalled = 0;\n\n    nock('https://hub-cloud.browserstack-ats.com')\n      .post('/wd/hub/session')\n      .reply(201, function (uri, requestBody) {\n        return {\n          value: {\n            sessionId: '1352110219202',\n            capabilities: requestBody.capabilities\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate-turboscale/v1/builds?status=running&limit=20&offset=0')\n      .reply(200, function() {\n        buildsMockCalled++;\n\n        return {'builds': []};\n      });\n    nock('https://api.browserstack.com')\n      .get('/automate-turboscale/v1/builds?status=running&limit=20&offset=20')\n      .reply(200, function() {\n        buildsMockCalled++;\n\n        return {'builds': []};\n      });\n\n    assert.ok(client.transport instanceof AutomateTurboScale);\n    assert.strictEqual(client.settings.webdriver.host, 'hub-cloud.browserstack-ats.com');\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n    assert.strictEqual(client.settings.webdriver.ssl, true);\n\n    const {transport} = client;\n    assert.ok(transport instanceof SeleniumRemote);\n\n    let result = await transport.createSession({argv: undefined, moduleKey: ''});\n    assert.strictEqual(result.sessionId, '1352110219202');\n\n    client.emit('nightwatch:session.create', result);\n\n    assert.strictEqual(transport.username, 'test-access-user');\n    assert.strictEqual(transport.accessKey, 'test-access-key');\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n\n    let sessionNockCalled = 0;\n\n    nock('https://api.browserstack.com')\n      .get('/automate-turboscale/v1/sessions/1352110219202')\n      .reply(200, function(){\n        sessionNockCalled++;\n\n        return {status: 'done'};\n      });\n    nock('https://api.browserstack.com')\n      .patch('/automate-turboscale/v1/sessions/1352110219202', {\n        status: 'passed',\n        reason: ''\n      })\n      .reply(200, function(){\n        sessionNockCalled++;\n\n        return {};\n      });\n\n    result = await transport.testSuiteFinished(false);\n    assert.strictEqual(result, true);\n    assert.strictEqual(transport.sessionId, null);\n\n    assert.strictEqual(sessionNockCalled, 2);\n    assert.strictEqual(buildsMockCalled, 1);\n    assert.strictEqual(transport.buildId, undefined);\n  });\n\n});\n"
  },
  {
    "path": "test/src/index/transport/testChromeOptions.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../../lib/nightwatch.js');\nconst ChromeOptions = require('selenium-webdriver/chrome').Options;\n\ndescribe('Test chrome options', function () {\n  it('Chrome option object with headless', function(){\n    const capabilities = new ChromeOptions();\n    capabilities.addArguments('headless=new');\n\n    const client = Nightwatch.createClient({\n      capabilities\n    });\n    \n    const options = client.transport.createSessionOptions();\n    assert.strictEqual(options, capabilities);\n    assert.strictEqual(client.api.isChrome(), true);\n    assert.strictEqual(client.api.browserName, 'chrome');\n  });\n\n  it('goog:chromeOptions detach driver option', function () {\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {\n          detach: true\n        }\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.strictEqual(options.options_.detach, true);\n    assert.strictEqual(client.api.isChrome(), true);\n    assert.strictEqual(client.api.browserName, 'chrome');\n  });\n\n  it('chromeOptions detach driver option', function () {\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        chromeOptions: {\n          detach: true\n        }\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.strictEqual(options.options_.detach, true);\n    assert.strictEqual(client.api.isChrome(), true);\n    assert.strictEqual(client.api.browserName, 'chrome');\n  });\n\n  it('Chrome Binary Path option', function(){\n    const client = Nightwatch.createClient({\n      webdriver: {\n        chrome_binary: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'\n      },\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.strictEqual(options.options_.binary, '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome');\n    assert.strictEqual(client.api.isChrome(), true);\n    assert.strictEqual(client.api.browserName, 'chrome');\n  });\n\n  it('Chrome log path option', function(){\n    const client = Nightwatch.createClient({\n      webdriver: {\n        chrome_log_file: '/Nightwatch/ChromeLog/'\n      },\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.strictEqual(options.options_.logPath, '/Nightwatch/ChromeLog/');\n\n  });\n\n  it('Andriod chrome option', function() {\n    const client = Nightwatch.createClient({\n      webdriver: {\n        android_chrome: 'com.android.chrome'\n      },\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n    \n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.strictEqual(options.options_.androidPackage, 'com.android.chrome');\n  });\n\n  it('headless option', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    });\n    const options = client.transport.createSessionOptions({headless: true});\n\n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.deepStrictEqual(options.options_.args, ['headless=new']);\n  });\n\n  it('devtools cli arg', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    });\n\n    const options = client.transport.createSessionOptions({devtools: true});\n\n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.deepStrictEqual(options.options_.args, ['auto-open-devtools-for-tabs']);\n  });\n\n  it('devtools cli arg with already defined setting', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {\n          args: ['auto-open-devtools-for-tabs']\n        }\n      }\n    });\n\n    const options = client.transport.createSessionOptions({devtools: true});\n\n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.deepStrictEqual(options.options_.args, ['auto-open-devtools-for-tabs']);\n  });\n\n  it('devtools cli arg with already defined setting 2', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {\n          args: ['--auto-open-devtools-for-tabs']\n        }\n      }\n    });\n\n    const options = client.transport.createSessionOptions({devtools: true});\n\n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.deepStrictEqual(options.options_.args, ['--auto-open-devtools-for-tabs']);\n  });\n\n  it('devtools cli arg with already defined setting (using chromeOptions)', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        chromeOptions: {\n          args: ['auto-open-devtools-for-tabs']\n        }\n      }\n    });\n\n    const options = client.transport.createSessionOptions({devtools: true});\n\n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.deepStrictEqual(options.options_.args, ['auto-open-devtools-for-tabs']);\n  });\n\n  it('window size option', function(){\n    const client =  Nightwatch.createClient({\n      window_size: {\n        height: 100,\n        width: 100\n      },\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    });\n    const options =  client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.deepStrictEqual(options.options_.args, ['window-size=100,100']);\n  });\n\n  it('proxy option', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        proxy: {\n          https: 'localhost:8888'\n        }\n      }\n    });\n    const options = client.transport.createSessionOptions();\n    \n    assert.strictEqual(options instanceof ChromeOptions, true);\n    assert.deepStrictEqual(options.getProxy(), {\n      proxyType: 'manual',\n      sslProxy: 'localhost:8888',\n      ftpProxy: undefined,\n      httpProxy: undefined,\n      noProxy: undefined\n    });\n  });\n  \n  it('always match in desired capabilties', function() {\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'chrome',\n        alwaysMatch: {\n          acceptInsecureCerts: true,\n          'goog:chromeOptions': {\n            args: [\n              '--headless'\n            ]\n          }\n        }\n      }\n    });\n\n    const options = client.transport.createSessionOptions();\n    assert.ok(options instanceof ChromeOptions);\n    assert.strictEqual(options.get('acceptInsecureCerts'), true);\n    assert.deepStrictEqual(options.get('goog:chromeOptions'), {\n      args: ['--headless']\n    });\n  });\n\n  \n});\n"
  },
  {
    "path": "test/src/index/transport/testCreateTransport.js",
    "content": "const assert = require('assert');\nconst common = require('../../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst SeleniumRemote = common.require('transport/selenium-webdriver/selenium.js');\nconst GeckoDriver = common.require('transport/selenium-webdriver/firefox.js');\nconst ChromeDriver = common.require('transport/selenium-webdriver/chrome.js');\nconst EdgeDriver = common.require('transport/selenium-webdriver/edge.js');\nconst SafariDriver = common.require('transport/selenium-webdriver/safari.js');\n\ndescribe('Transport.create()', function () {\n  it('test create Transport for Selenium external with Firefox', function() {\n    const client = NightwatchClient.client({\n      selenium: {\n        start_process: false\n      },\n      webdriver: {},\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      selenium_host: 'remote.url'\n    });\n\n    assert.ok(client.transport instanceof SeleniumRemote);\n    assert.strictEqual(client.settings.webdriver.host, 'remote.url');\n  });\n\n  it('test create Transport for Selenium external with Firefox - seleniumHost property', function() {\n    const client = NightwatchClient.client({\n      selenium: {\n        start_process: false\n      },\n      webdriver: {},\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      seleniumHost: 'remote.url'\n    });\n\n    assert.ok(client.transport instanceof SeleniumRemote);\n    assert.strictEqual(client.settings.webdriver.host, 'remote.url');\n  });\n\n  it('test create Transport for Webdriver external - host property', function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        host: 'remote.url'\n      },\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    });\n\n    assert.ok(client.transport instanceof GeckoDriver);\n    assert.strictEqual(client.settings.webdriver.host, 'remote.url');\n  });\n\n  it('test create Transport for Selenium external with Chrome', function() {\n    const client = NightwatchClient.client({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium_host: 'remote.url'\n    });\n\n    assert.ok(client.transport instanceof SeleniumRemote);\n    assert.strictEqual(client.settings.webdriver.host, 'remote.url');\n  });\n\n  it('test create Transport for Selenium managed', function() {\n    const client = NightwatchClient.client({\n      selenium: {\n        start_process: true\n      },\n      webdriver: {\n        start_process: false\n      },\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    });\n\n    assert.ok(client.transport instanceof SeleniumRemote);\n  });\n\n  it('test create Transport with unknown browser', function() {\n    assert.throws(function() {\n      NightwatchClient.client({\n        webdriver: {\n          start_process: true\n        },\n        desiredCapabilities: {\n          browserName: 'firfox'\n        }\n      });\n    }, /Unknown browser: \"firfox\"; did you mean \"firefox\"\\?$/);\n  });\n\n  it('test create Transport for Firefox managed', function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    });\n\n    assert.ok(client.transport instanceof GeckoDriver);\n    assert.strictEqual(client.transport instanceof SeleniumRemote, false);\n  });\n\n  it('test create Transport for Chrome managed', function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    });\n\n    assert.ok(client.transport instanceof ChromeDriver);\n    assert.strictEqual(client.transport instanceof SeleniumRemote, false);\n    assert.deepStrictEqual(client.transport.desiredCapabilities, {\n      browserName: 'chrome'\n    });\n  });\n\n  it('test create Transport for Chrome managed with w3c:true', function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {\n          w3c: true\n        }\n      }\n    });\n\n    assert.ok(client.transport instanceof ChromeDriver);\n    assert.strictEqual(client.transport instanceof SeleniumRemote, false);\n    assert.deepStrictEqual(client.transport.desiredCapabilities, {\n      browserName: 'chrome',\n      'goog:chromeOptions': {\n        w3c: true\n      }\n    });\n  });\n\n  it('test create Transport for Chrome managed with w3c:false', function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'chrome',\n        'goog:chromeOptions': {\n          w3c: false\n        }\n      }\n    });\n\n    assert.ok(client.transport instanceof ChromeDriver);\n    assert.strictEqual(client.transport instanceof SeleniumRemote, false);\n    assert.deepStrictEqual(client.transport.desiredCapabilities, {\n      browserName: 'chrome',\n      'goog:chromeOptions': {\n        w3c: false\n      }\n    });\n  });\n\n  it('test create Transport for Edge managed with w3c:true', function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'MicrosoftEdge',\n        'ms:edgeOptions': {\n          w3c: true\n        }\n      }\n    });\n\n    assert.ok(client.transport instanceof EdgeDriver);\n    assert.strictEqual(client.transport instanceof SeleniumRemote, false);\n    assert.deepStrictEqual(client.transport.desiredCapabilities, {\n      browserName: 'MicrosoftEdge',\n      'ms:edgeOptions': {\n        w3c: true\n      }\n    });\n  });\n\n  it('test create Transport for Edge managed', function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'MicrosoftEdge'\n      }\n    });\n\n    assert.ok(client.transport instanceof EdgeDriver);\n    assert.strictEqual(client.transport instanceof SeleniumRemote, false);\n    assert.deepStrictEqual(client.transport.desiredCapabilities, {\n      browserName: 'MicrosoftEdge'\n    });\n  });\n\n  it('test create Transport for Edge managed with w3c:false', function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'MicrosoftEdge',\n        'ms:edgeOptions': {\n          w3c: false\n        }\n      }\n    });\n\n    assert.strictEqual(client.transport instanceof SeleniumRemote, false);\n    assert.strictEqual(client.transport instanceof EdgeDriver, true);\n    assert.deepStrictEqual(client.transport.desiredCapabilities, {\n      browserName: 'MicrosoftEdge',\n      'ms:edgeOptions': {\n        w3c: false\n      }\n    });\n  });\n\n  it('test create Transport for Safari managed', function() {\n    let client = NightwatchClient.client({\n      selenium: {\n        start_process: false\n      },\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'safari'\n      }\n    });\n\n    assert.ok(client.transport instanceof SafariDriver);\n    assert.strictEqual(client.transport instanceof SeleniumRemote, false);\n  });\n\n  it('test create Transport for Safari remote', function() {\n    const Transport = common.require('transport/index.js');\n\n    let safariDriver = Transport.create({\n      settings: {\n        selenium: {\n          start_process: false\n        },\n        webdriver: {\n          start_process: false,\n          host: 'remote.url'\n        },\n        desiredCapabilities: {\n          browserName: 'safari'\n        }\n      }\n    });\n\n    assert.ok(safariDriver instanceof SafariDriver);\n    assert.strictEqual(safariDriver instanceof SeleniumRemote, false);\n  });\n\n  it('test create Transport for Chrome managed and no selenium settings', function() {\n    const Transport = common.require('transport/index.js');\n\n    let chromeDriver = Transport.create({\n      settings: {\n        webdriver: {\n          start_process: true\n        },\n        desiredCapabilities: {\n          browserName: 'chrome'\n        }\n      }\n    });\n\n    assert.ok(chromeDriver instanceof ChromeDriver);\n    assert.strictEqual(chromeDriver instanceof SeleniumRemote, false);\n  });\n\n  it('test create Transport for WebDriver managed and no selenium settings', function() {\n    const client = NightwatchClient.client({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'safari'\n      }\n    });\n\n    assert.ok(client.transport instanceof SafariDriver);\n    assert.strictEqual(client.transport instanceof SeleniumRemote, false);\n  });\n\n  it('test check for ssl when webdriver port is 443', function () {\n    const Transport = common.require('transport/index.js');\n    const Settings = common.require('settings/settings.js');\n\n    const settings = Settings.fromClient({\n      webdriver: {\n        start_process: true,\n        port: 443,\n        host: 'remote.host'\n      },\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    });\n\n    const instance = {\n      settings\n    };\n\n    const chromeDriver = Transport.create(instance);\n    assert.strictEqual(instance.settings.webdriver.ssl, true);\n  });\n\n  it('test create Transport for Selenium remote cloud service with Chrome', function() {\n    const client = NightwatchClient.client({\n      selenium: {\n        start_process: false\n      },\n      desiredCapabilities: {\n        browserName: 'Chrome'\n      },\n      selenium_host: 'remote.host'\n    });\n\n    assert.ok(client.transport instanceof SeleniumRemote);\n\n    const elementId = client.transport.getElementId({\n      'element-6066-11e4-a52e-4f735466cecf': 'abcd-123'\n    });\n    assert.strictEqual(elementId, 'abcd-123');\n    assert.strictEqual(client.settings.webdriver.host, 'remote.host');\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n  });\n\n  it('test create Transport for Selenium remote cloud service with MicrosoftEdge', function() {\n    const client = NightwatchClient.client({\n      selenium: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'MicrosoftEdge'\n      },\n      selenium_host: 'remote.host'\n    });\n\n    assert.ok(client.transport instanceof SeleniumRemote);\n    assert.strictEqual(client.settings.webdriver.host, 'remote.host');\n    assert.strictEqual(client.settings.webdriver.default_path_prefix, '/wd/hub');\n  });\n\n});\n"
  },
  {
    "path": "test/src/index/transport/testEdgeOptions.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../../lib/nightwatch.js');\nconst EdgeOptions =  require('selenium-webdriver/edge').Options;\n\ndescribe('Test edge option', function(){\n  \n  it('Edge option object with headless', function(){\n    const edgeoptions = new EdgeOptions();\n    edgeoptions.addArguments('headless=new');\n\n    const client = Nightwatch.createClient({\n      capabilities: edgeoptions\n    });\n\n    const options =  client.transport.createSessionOptions();\n    assert.strictEqual(options, edgeoptions);\n    assert.strictEqual(client.api.isEdge(), true);\n    assert.strictEqual(client.api.browserName, 'MicrosoftEdge');\n  });\n\n  it('ms:edgeOption detach driver option', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'edge',\n        'ms:edgeOptions': {\n          detach: true\n        }\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof EdgeOptions, true);\n    assert.strictEqual(options.options_.detach, true);\n    assert.strictEqual(client.api.isEdge(), true);\n    assert.strictEqual(client.api.browserName, 'edge');\n  });\n  \n  it('Edge Binary Path option', function(){\n    const client = Nightwatch.createClient({\n      webdriver: {\n        edge_binary: '/Applications/Edge.app/Contents/MacOS/Edge'\n      },\n      desiredCapabilities: {\n        browserName: 'edge'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof EdgeOptions, true);\n    assert.strictEqual(options.options_.binary, '/Applications/Edge.app/Contents/MacOS/Edge');\n  });\n\n  it('Edge log path option', function(){\n    const client = Nightwatch.createClient({\n      webdriver: {\n        edge_log_file: '/Nightwatch/EdgeLog/'\n      },\n      desiredCapabilities: {\n        browserName: 'edge'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof EdgeOptions, true);\n    assert.strictEqual(options.options_.logPath, '/Nightwatch/EdgeLog/');\n\n  });\n\n  it('headless option', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'edge'\n      }\n    });\n    const options = client.transport.createSessionOptions({headless: true});\n\n    assert.strictEqual(options instanceof EdgeOptions, true);\n    assert.deepStrictEqual(options.options_.args, ['headless=new']);\n  });\n\n  it('window size option', function(){\n    const client =  Nightwatch.createClient({\n      window_size: {\n        height: 100,\n        width: 100\n      },\n      desiredCapabilities: {\n        browserName: 'edge'\n      }\n    });\n    const options =  client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof EdgeOptions, true);\n    assert.deepStrictEqual(options.options_.args, ['window-size=100,100']);\n  });\n\n  it('Andriod package option', function() {\n    const client = Nightwatch.createClient({\n      webdriver: {\n        android_package: 'com.android.edge'\n      },\n      desiredCapabilities: {\n        browserName: 'edge'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n    \n    assert.strictEqual(options instanceof EdgeOptions, true);\n    assert.strictEqual(options.options_.androidPackage, 'com.android.edge');\n  });\n\n  it('proxy option', function(){\n    const client =  Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'edge',\n        proxy: {\n          https: 'localhost:8888'\n        }\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof EdgeOptions, true);\n    assert.deepStrictEqual(options.getProxy(), {\n      proxyType: 'manual',\n      sslProxy: 'localhost:8888',\n      ftpProxy: undefined,\n      httpProxy: undefined,\n      noProxy: undefined\n    });\n  });\n\n  it('msedge as browserName', function () {\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'msedge'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof EdgeOptions, true);\n    assert.strictEqual(client.api.isEdge(), true);\n    assert.strictEqual(client.api.browserName, 'msedge');\n  });\n\n});\n"
  },
  {
    "path": "test/src/index/transport/testFirefoxOptions.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../../lib/nightwatch.js');\nconst FirefoxOptions =  require('selenium-webdriver/firefox').Options;\n\ndescribe('Firefox driver options', function(){\n\n  it('Firefox option object with headless', function(){\n    const firefoxOptions =  new FirefoxOptions();\n    firefoxOptions.addArguments('-headless');\n\n    const client = Nightwatch.createClient({\n      capabilities: firefoxOptions\n    });\n\n    const options =  client.transport.createSessionOptions();\n    assert.strictEqual(options, firefoxOptions);\n    assert.strictEqual(client.api.isFirefox(), true);\n    assert.strictEqual(client.api.browserName, 'firefox');\n  });\n\n  it('moz:firefoxOptions detach driver option', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'firefox',\n        'moz:firefoxOptions': {\n          detach: true\n        }\n      }\n    });\n    const options =  client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof FirefoxOptions, true);\n    assert.deepStrictEqual(options.get('moz:firefoxOptions').detach, true);\n    assert.strictEqual(client.api.isFirefox(), true);\n    assert.strictEqual(client.api.browserName, 'firefox');\n  });\n\n  it('Firefox Binary Path option', function(){\n    const client = Nightwatch.createClient({\n      webdriver: {\n        firefox_binary: '/Applications/Firefox.app/Contents/MacOS/Firefox'\n      },\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof FirefoxOptions, true);\n    assert.strictEqual(options.get('moz:firefoxOptions').binary, '/Applications/Firefox.app/Contents/MacOS/Firefox');\n  });\n\n  it('Firefox log path option', function(){\n    const client = Nightwatch.createClient({\n      webdriver: {\n        firefox_profile: 'Nightwatch'\n      },\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof FirefoxOptions, true);\n    assert.strictEqual(options.get('moz:firefoxOptions').profile.template_, 'Nightwatch');\n\n  });\n\n  it('headless option', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    });\n    const options = client.transport.createSessionOptions({headless: true});\n\n    assert.strictEqual(options instanceof FirefoxOptions, true);\n    assert.deepStrictEqual(options.get('moz:firefoxOptions').args, ['-headless']);\n  });\n\n  it('window size option', function(){\n    const client = Nightwatch.createClient({\n      window_size: {\n        height: 100,\n        width: 100\n      },\n      desiredCapabilities: {\n        browserName: 'firefox'\n      }\n    });\n\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof FirefoxOptions, true);\n    assert.deepStrictEqual(options.get('moz:firefoxOptions').args, ['--width=100', '--height=100']);\n  });\n  \n  it('proxy options', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        proxy: {\n          https: 'localhost:8888'\n        },\n        browserName: 'firefox'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof FirefoxOptions, true);\n    assert.deepStrictEqual(options.getProxy(), {\n      proxyType: 'manual',\n      sslProxy: 'localhost:8888',\n      ftpProxy: undefined,\n      httpProxy: undefined,\n      noProxy: undefined\n    });\n  });\n\n  it('always match in desired capabilties', function() {\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        desiredCapabilities: 'firefox',\n        alwaysMatch: {\n          acceptInsecureCerts: true,\n          'moz:firefoxOptions': {\n            args: [\n              '--headless'\n            ]\n          }\n        }\n      }\n    });\n\n    const options = client.transport.createSessionOptions();\n    assert.ok(options instanceof FirefoxOptions);\n    assert.strictEqual(options.get('acceptInsecureCerts'), true);\n    assert.deepStrictEqual(options.get('moz:firefoxOptions'), {\n      args: ['--headless'],\n      prefs: {'remote.active-protocols': 3}\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/index/transport/testIeOptions.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../../lib/nightwatch.js');\nconst IeOptions =  require('selenium-webdriver/ie').Options;\n\ndescribe('Internet Explorer driver options', function(){\n\n  it('Internet Explorer option object defaults', function(){\n    const ieOptions =  new IeOptions();\n    const client = Nightwatch.createClient({\n      capabilities: ieOptions\n    });\n\n    const options =  client.transport.createSessionOptions({initialBrowserUrl: 'https://google.com'});\n    assert.deepStrictEqual(options, ieOptions);\n    assert.strictEqual(client.api.isInternetExplorer(), true);\n    assert.strictEqual(client.api.browserName, 'internet explorer');\n  });\n\n  it('Internet Explorer with instance of IeOptions', function(){\n    const ieOptions =  new IeOptions();\n    const client = Nightwatch.createClient({\n      desiredCapabilities: ieOptions\n    });\n\n    const options =  client.transport.createSessionOptions();\n    assert.deepStrictEqual(options, ieOptions);\n    assert.strictEqual(client.api.isInternetExplorer(), true);\n    assert.strictEqual(client.api.browserName, 'internet explorer');\n  });\n\n  it('IE initialBrowserUrl option', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'internet explorer',\n        'se:ieOptions': {\n          initialBrowserUrl: 'https://nightwatchjs.org'\n        }\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof IeOptions, true);\n    assert.strictEqual(options.get('se:ieOptions').initialBrowserUrl, 'https://nightwatchjs.org');\n  });\n\n  it('IE ensureCleanSession option', function(){\n    const client = Nightwatch.createClient({\n      desiredCapabilities: {\n        browserName: 'internet explorer',\n        'se:ieOptions': {\n          ensureCleanSession: true\n        }\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof IeOptions, true);\n    assert.strictEqual(options.get('se:ieOptions').ensureCleanSession, true);\n  });\n\n  it('IE log path option', function(){\n    const client = Nightwatch.createClient({\n      webdriver: {\n        log_path: '/custom/log/path'\n      },\n      desiredCapabilities: {\n        browserName: 'internet explorer'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof IeOptions, true);\n    assert.strictEqual(options.get('se:ieOptions').logFile, '/custom/log/path');\n  });\n\n  it('IE host option', function(){\n    const client = Nightwatch.createClient({\n      webdriver: {\n        host: '10.0.0.1'\n      },\n      desiredCapabilities: {\n        browserName: 'internet explorer'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof IeOptions, true);\n    assert.strictEqual(options.get('se:ieOptions').host, '10.0.0.1');\n  });\n});\n"
  },
  {
    "path": "test/src/index/transport/testMobileOptions.js",
    "content": "const assert = require('assert');\nconst {describe} = require('mocha');\nconst common = require('../../../common.js');\nconst Nightwatch = require('../../../lib/nightwatch.js');\nconst Appium = common.require('transport/selenium-webdriver/appium.js');\nconst ChromeDriver = common.require('transport/selenium-webdriver/chrome.js');\nconst SafariDriver = common.require('transport/selenium-webdriver/safari.js');\n\ndescribe('Test mobile options in Nightwatch/Appium client', function () {\n  it('have isIOS() for web testing on iOS', function () {\n    const client = Nightwatch.createClient({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'Safari',\n        javascriptEnabled: true,\n        platformName: 'iOS',\n        platformVersion: '15.0',\n        deviceName: 'iPhone 13'\n      }\n    });\n    client.transport.createSessionOptions();\n\n    assert.ok(client.transport instanceof SafariDriver);\n    assert.strictEqual(client.api.isIOS(), true);\n    assert.strictEqual(client.api.isAndroid(), false);\n    assert.strictEqual(client.api.isMobile(), true);\n    assert.strictEqual(client.api.isAppiumClient(), false);\n  });\n\n  it('have isAndroid() for web testing on Android', function () {\n    const client = Nightwatch.createClient({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'Chrome',\n        javascriptEnabled: true,\n        'goog:chromeOptions': {\n          androidPackage: 'com.android.chrome'\n        }\n      }\n    });\n\n    client.transport.createSessionOptions();\n\n    assert.ok(client.transport instanceof ChromeDriver);\n    assert.strictEqual(client.api.isIOS(), false);\n    assert.strictEqual(client.api.isAndroid(), true);\n    assert.strictEqual(client.api.isMobile(), true);\n    assert.strictEqual(client.api.isAppiumClient(), false);\n  });\n\n  it('doesn\\'t have isIOS(), isAndroid() and isMobile() for web testing on desktop', function () {\n    const client = Nightwatch.createClient({\n      webdriver: {\n        start_process: true\n      },\n      desiredCapabilities: {\n        browserName: 'Chrome'\n      }\n    });\n\n    client.transport.createSessionOptions();\n\n    assert.ok(client.transport instanceof ChromeDriver);\n    assert.strictEqual(client.api.isIOS(), false);\n    assert.strictEqual(client.api.isAndroid(), false);\n    assert.strictEqual(client.api.isMobile(), false);\n    assert.strictEqual(client.api.isAppiumClient(), false);\n  });\n\n  it('have isIOS() and isAppiumClient() for native testing on iOS', function () {\n    const client = Nightwatch.createClient({\n      selenium: {\n        use_appium: true\n      },\n      desiredCapabilities: {\n        browserName: null,\n        platformName: 'iOS',\n        platformVersion: '15.0',\n        deviceName: 'iPhone 13'\n      }\n    });\n    client.transport.createSessionOptions();\n\n    assert.ok(client.transport instanceof Appium);\n    assert.strictEqual(client.api.isIOS(), true);\n    assert.strictEqual(client.api.isAndroid(), false);\n    assert.strictEqual(client.api.isMobile(), true);\n    assert.strictEqual(client.api.isAppiumClient(), true);\n  });\n\n  it('have isAndroid() for native testing on Android', function () {\n    const client = Nightwatch.createClient({\n      selenium: {\n        use_appium: false\n      },\n      desiredCapabilities: {\n        browserName: null,\n        platformName: 'Android'\n      }\n    });\n\n    client.transport.createSessionOptions();\n\n    assert.ok(client.transport instanceof Appium);\n    assert.strictEqual(client.api.isIOS(), false);\n    assert.strictEqual(client.api.isAndroid(), true);\n    assert.strictEqual(client.api.isMobile(), true);\n    // backward compatibility with browserName: null\n    assert.strictEqual(client.api.isAppiumClient(), true);\n  });\n\n  it('have isAndroid() and isAppiumClient() for web testing on Android using Appium', function () {\n    const client = Nightwatch.createClient({\n      selenium: {\n        use_appium: true\n      },\n      desiredCapabilities: {\n        browserName: 'Chrome',\n        platformName: 'Android'\n      }\n    });\n\n    client.transport.createSessionOptions();\n\n    assert.ok(client.transport instanceof Appium);\n    assert.strictEqual(client.api.isIOS(), false);\n    assert.strictEqual(client.api.isAndroid(), true);\n    assert.strictEqual(client.api.isMobile(), true);\n    assert.strictEqual(client.api.isAppiumClient(), true);\n  });\n});\n"
  },
  {
    "path": "test/src/index/transport/testMobileWebSupport.js",
    "content": "const assert = require('assert');\nconst common = require('../../../common.js');\nconst path = require('path');\nconst CommandGlobals = require('../../../lib/globals/commands.js');\nconst MockServer = require('../../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\nconst Transport = common.require('transport/selenium-webdriver/index.js');\nconst {IosSessionNotCreatedError, AndroidConnectionError} = common.require('utils/mobile.js');\nconst mockery = require('mockery');\n\ndescribe('MobileSupport', function () {\n  before(function () {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n  });\n\n  beforeEach(function (done) {\n    this.getDriverBackup = Transport.prototype.getDriver;\n    this.createDriverServiceBackup = Transport.prototype.createDriverService;\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n    Transport.prototype.getDriver = this.getDriverBackup;\n    Transport.prototype.createDriverService = this.createDriverServiceBackup;\n\n    CommandGlobals.afterEach.call(this, function () {\n      done();\n    });\n  });\n\n  it('error classes for mobile-web support - RealIosDeviceIdError', function () {\n    const src_folders = [\n      path.join(__dirname, '../../../sampletests/withsubfolders')\n    ];\n\n    return runTests({}, settings({\n      output: false,\n      src_folders,\n      desiredCapabilities: {\n        browserName: 'safari',\n        platformName: 'iOS',\n        alwaysMatch: {\n          acceptInsecureCerts: false\n        }\n      },\n\n      webdriver: {\n        start_process: true,\n        server_path: '',\n        cli_args: [\n          // --verbose\n        ]\n      }\n    })).catch(err => {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.name, 'RealIosDeviceIdError');\n      assert.strictEqual(err.message, 'Real Device ID is neither configured nor passed');\n      assert.strictEqual(err.help.length, 4);\n    });\n  });\n\n  it('error classes for mobile-web support - IosSessionNotCreatedError', function () {\n    Transport.prototype.getDriver = function() {\n      const err = new Error('An error occurred while creating a new SafariDriver session');\n      err.name = 'SessionNotCreatedError';\n\n      throw err;\n    };\n\n    Transport.prototype.createDriverService = async function() { \n      this.driverService = {\n        getOutputFilePath(){},\n        getSettingsFormatted(){}\n      };\n    };\n\n    const src_folders = [\n      path.join(__dirname, '../../../sampletests/withfailures'),\n      path.join(__dirname, '../../../sampletests/withsubfolders')\n    ];\n\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.ok(results.lastError instanceof Error);\n        assert.ok(results.lastError instanceof IosSessionNotCreatedError);\n        assert.ok(Object.prototype.hasOwnProperty.call(results.lastError, 'name'));\n        assert.ok(Object.prototype.hasOwnProperty.call(results.lastError, 'message'));\n        assert.ok(results.lastError.help.length, 3);\n        cb();\n      }\n    };\n\n    return runTests({\n    }, settings({\n      output: false,\n      src_folders,\n      globals,\n      desiredCapabilities: {\n        browserName: 'safari',\n        platformName: 'iOS',\n        'safari:deviceUDID': '00008030-00024C2C3453402E',\n        alwaysMatch: {\n          acceptInsecureCerts: false\n        }\n      },\n    \n      webdriver: {\n        start_process: true,\n        server_path: '',\n        cli_args: [\n          // --verbose\n        ]\n      }\n    }));\n  });\n\n  it('deviceId passed as argument - real device', async function () {\n    const CliRunner = common.require('runner/cli/cli.js');\n    \n    const runner = new CliRunner({\n      reporter: 'junit',\n      env: 'mixed',\n      deviceId: '00008030-00024C2C3453402E'\n    });\n\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 0\n    };\n\n    await runner.setupAsync(settings({\n      output: false,\n      globals,\n      desiredCapabilities: {\n        browserName: 'safari',\n        platformName: 'iOS',\n        alwaysMatch: {\n          acceptInsecureCerts: false\n        }\n      },\n\n      webdriver: {\n        start_process: true,\n        server_path: '',\n        cli_args: [\n          // --verbose\n        ]\n      }\n    }));\n\n    assert.strictEqual(runner.test_settings.desiredCapabilities['safari:deviceUDID'], '00008030-00024C2C3453402E');\n    assert.strictEqual(runner.test_settings.desiredCapabilities.platformName, 'iOS');\n    assert.ok(!runner.test_settings.desiredCapabilities['safari:useSimulator']);\n  });\n\n  it('error classes for mobile-web support - AndroidConnectionError', async function () {\n    this.timeout(10000);\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n\n    mockery.registerMock('../androidEmulator.js', class AndroidServer {\n      constructor() {}\n\n      launchEmulator() {\n        return Promise.resolve();\n      }\n\n      killEmulator() {}\n    });\n\n    Transport.prototype.getDriver = function() {\n      const err = new Error('unknown error: There are no devices online');\n      err.name = 'SessionNotCreatedError';\n\n      throw err;\n    };\n\n    Transport.prototype.createDriverService = async function() { \n      this.driverService = {\n        stop() {},\n        getOutputFilePath(){},\n        getSettingsFormatted(){}\n      };\n    };\n\n    mockery.registerMock('./', Transport);\n    mockery.registerMock('@nightwatch/mobile-helper', {\n      getBinaryLocation(){},\n      getPlatformName(){}\n    });\n\n    const src_folders = [\n      path.join(__dirname, '../../../sampletests/withsubfolders/simple')\n    ];\n\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.ok(results.lastError instanceof Error);\n        assert.ok(results.lastError instanceof AndroidConnectionError);\n        assert.ok(results.lastError.message.includes('no devices online'));\n        assert.ok(Object.prototype.hasOwnProperty.call(results.lastError, 'message'));\n        // assert.ok(results.lastError.help.length, 4);\n        cb();\n      }\n    };\n\n    let error;\n    try {\n      await runTests({}, settings({\n        output: false,\n        src_folders,\n        globals,\n        desiredCapabilities: {\n          real_mobile: false,\n          browserName: 'chrome',\n          avd: 'dummy',\n          'goog:chromeOptions': {\n            androidPackage: 'com.android.chrome'\n          }\n        },\n        webdriver: {\n          start_process: true,\n          server_path: '',\n          cli_args: [\n            // --verbose\n          ]\n        }\n      }));\n    } catch (err) {\n      error = err;\n    }\n\n    assert.strictEqual(error, undefined);\n  });\n});\n"
  },
  {
    "path": "test/src/index/transport/testSafariOptions.js",
    "content": "const assert = require('assert');\nconst Nightwatch = require('../../../lib/nightwatch.js');\nconst SafariOptions =  require('selenium-webdriver/safari').Options;\n\ndescribe('Test safari options', function(){\n\n  it('Safari option object with technology preview', function(){\n    const safariOptions =  new SafariOptions();\n    safariOptions.setTechnologyPreview(true);\n\n    const client = Nightwatch.createClient({\n      capabilities: safariOptions\n    });\n    const options =  client.transport.createSessionOptions();\n    \n    assert.strictEqual(options, safariOptions);\n    assert.strictEqual(client.api.isSafari(), true);\n    assert.strictEqual(client.api.browserName, 'safari');\n  });\n\n  it('proxy option', function(){\n    const client =  Nightwatch.createClient({\n      desiredCapabilities: {\n        proxy: {\n          https: 'localhost:8888'\n        },\n        browserName: 'safari'\n      }\n    });\n    const options = client.transport.createSessionOptions();\n\n    assert.strictEqual(options instanceof SafariOptions, true);\n    assert.deepStrictEqual(options.getProxy(), {\n      proxyType: 'manual',\n      sslProxy: 'localhost:8888',\n      ftpProxy: undefined,\n      httpProxy: undefined,\n      noProxy: undefined\n    });\n  });\n  \n\n});"
  },
  {
    "path": "test/src/index/transport/testSeleniumTransport.js",
    "content": "const assert = require('assert');\nconst common = require('../../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst SeleniumRemote = common.require('transport/selenium-webdriver/selenium.js');\nconst Concurrency = common.require('runner/concurrency/');\nconst MockServer = require('../../../lib/mockserver.js');\nconst CommandGlobals = require('../../../lib/globals/commands.js');\n\ndescribe('Selenium Server Transport', function () {\n  const fn = Concurrency.isWorker;\n  before(function(done) {\n    Concurrency.isWorker = function() {\n      return true;\n    }\n\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    Concurrency.isWorker = fn;\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('test create Transport with concurrency enabled', function() {\n    const client = NightwatchClient.client({\n      selenium: {\n        port: 10195,\n        host: 'localhost',\n        start_process: true\n      }\n    });\n\n    client.settings.selenium['[_started]'] = true;\n\n    const transport = new SeleniumRemote(client);\n    assert.strictEqual(client.settings.selenium.start_process, false);\n    assert.strictEqual(client.settings.webdriver.start_process, false);\n  });\n\n\n});\n"
  },
  {
    "path": "test/src/runner/cli/testCliRunnerParallel.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst mockery = require('mockery');\nconst common = require('../../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst {settings} = common;\n\ndescribe('Test CLI Runner in Parallel', function () {\n  const ChildProcess = common.require('runner/concurrency/child-process.js');\n  const WorkerProcess = common.require('runner/concurrency/worker-process.js');\n  const WorkerTask = common.require('runner/concurrency/worker-task.js');\n  const RunnerBase = common.require('runner/runner.js');\n\n  const filtered = Object.keys(require.cache).filter(item => (\n    item.endsWith('runner/runner.js') || item.endsWith('runner/concurrency/child-process.js') || item.endsWith('runner/concurrency/worker-process.js') || item.endsWith('runner/concurrency/worker-task.js')\n  ));\n\n  if (filtered && filtered.length > 0) {\n    filtered.forEach(item => {\n      delete require.cache[item];\n    });\n  }\n\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n  });\n\n  afterEach(function() {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n  });\n\n  it('test run geckodriver with concurrency - child process', function () {\n    class RunnerBaseMock extends RunnerBase {\n      static readTestSource(settings, argv) {\n        assert.strictEqual(settings.testWorkersEnabled, true);\n\n        return [\n          'test_file_1.js',\n          'test_file_2.js'\n        ];\n      }\n    }\n\n    class ChildProcessMock extends ChildProcess {\n      run(colors, type) {\n        assert.strictEqual(colors.length, 4);\n        assert.strictEqual(type, 'workers');\n        assert.deepStrictEqual(Object.keys(this._events), ['message']);\n\n        return Promise.resolve(0);\n      }\n    }\n\n    mockery.registerMock('./child-process.js', ChildProcessMock);\n    mockery.registerMock('../runner.js', RunnerBaseMock);\n\n    return NightwatchClient.runTests({\n      env: 'default',\n      config: path.join(__dirname, '../../../extra/withgeckodriver-concurrent.json')\n    }, {\n      use_child_process: true,\n      silent: false,\n      output: false,\n      output_folder: false\n    });\n  });\n  \n  it('test run geckodriver with concurrency - worker threads', function () {\n    process.env.TEST_ENV = 'TEST';\n    class RunnerBaseMock extends RunnerBase {\n      static readTestSource(settings, argv) {\n        assert.strictEqual(settings.testWorkersEnabled, true);\n\n        return [\n          'test_file_1.js',\n          'test_file_2.js'\n        ];\n      }\n    }\n\n    class WorkerProcessMock extends WorkerProcess {\n      addTask({colors}) {\n        assert.strictEqual(colors.length, 4);\n        assert.strictEqual(this.piscina.options.env.TEST_ENV, 'TEST');\n        assert(Object.keys(this.piscina.options.env).length > 1, 'process.env should have more than one key');\n\n        // cleaning the env\n        process.env.TEST_ENV = undefined;\n\n        return Promise.resolve(0);\n      }\n    }\n\n    mockery.registerMock('./worker-process.js', WorkerProcessMock);\n    mockery.registerMock('../runner.js', RunnerBaseMock);\n\n    return NightwatchClient.runTests({\n      env: 'default',\n      config: path.join(__dirname, '../../../extra/withgeckodriver-concurrent.json')\n    }, {\n      use_child_process: false,\n      silent: false,\n      output: false,\n      output_folder: false\n    });\n  });\n\n  it('run error test file with concurrency - worker threads', function() {\n    let numberOfTasks = 0;\n    class RunnerBaseMock extends RunnerBase {\n      static readTestSource(settings, argv) {\n        assert.strictEqual(settings.testWorkersEnabled, true);\n\n        return [\n          'test_file_1.js',\n          'test_file_2.js'\n        ];\n      }\n    }\n\n    class WorkerProcessMock extends WorkerProcess {\n      addTask({colors}) {\n\n        this.__tasks.push(new Promise((resolve, reject) => {\n          setTimeout(()=>{\n            numberOfTasks++;\n            reject(new Error('Nigtwatch custom error'));\n          }, 10 * (numberOfTasks + 1));\n        }));\n\n        return Promise.resolve(0);\n      }\n    }\n    mockery.registerMock('./worker-process.js', WorkerProcessMock);\n    mockery.registerMock('../runner.js', RunnerBaseMock);\n\n    return NightwatchClient.runTests({\n      env: 'default',\n      config: path.join(__dirname, '../../../extra/withgeckodriver-concurrent.json')\n    }, settings({\n      globals: {\n        reporter() {\n          assert.strictEqual(numberOfTasks, 2); \n        }\n      },\n      use_child_process: false,\n      silent: false,\n      output: false,\n      output_folder: false\n    }));\n  });\n\n  it('start single test run with geckodriver and test workers enabled', function () {\n    const testPath = path.join(__dirname, '../../../sampletests/async/test/sample.js');\n    const runner = NightwatchClient.CliRunner({\n      source: testPath\n    });\n\n    assert.strictEqual(runner.argv.source, undefined);\n    assert.deepStrictEqual(runner.argv._source, [testPath]);\n\n    runner.setup({\n      silent: false,\n      output: false,\n      output_folder: false\n    });\n\n    const Utils = common.require('utils');\n    assert.strictEqual(Utils.singleSourceFile(runner.argv), true);\n    assert.strictEqual(runner.isTestWorkersEnabled(), false);\n  });\n\n  it('mobile config setup on with worker threads - disabled parallelism ', function() {\n    class RunnerBaseMock extends RunnerBase {\n      static readTestSource(settings, argv) {\n        assert.strictEqual(settings.testWorkersEnabled, true);\n\n        return [\n          'test_file_1.js',\n          'test_file_2.js'\n        ];\n      }\n    }\n    mockery.registerMock('../runner.js', RunnerBaseMock);\n    mockery.registerMock(path.join(process.cwd(), 'ios_config.json'), {\n      test_settings: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        },\n        'simulator.ios': {\n          desiredCapabilities: {\n            browserName: 'safari',\n            platformName: 'iOS',\n            'safari:useSimulator': true,\n            'safari:deviceName': 'iPhone 13',\n            'safari:platformVersion': '15.0'\n          }\n        }\n      }\n    });\n    const runner = NightwatchClient.CliRunner({\n      config: 'ios_config.json',\n      env: 'simulator.ios',\n      workers: 4\n    }).setup();\n    assert.strictEqual(runner.isTestWorkersEnabled(), false);\n    assert.strictEqual(runner.parallelMode(), false);\n  });\n\n  it('mobile config setup on with worker threads - enable worker threads while using server config', function() {\n    class RunnerBaseMock extends RunnerBase {\n      static readTestSource(settings, argv) {\n        assert.strictEqual(settings.testWorkersEnabled, true);\n\n        return [\n          'test_file_1.js',\n          'test_file_2.js'\n        ];\n      }\n    }\n    mockery.registerMock('../runner.js', RunnerBaseMock);\n    mockery.registerMock(path.join(process.cwd(), 'ios_config.json'), {\n      test_settings: {\n        desiredCapabilities: {\n          browserName: 'firefox'\n        },\n        'simulator.ios': {\n          selenium: {\n            host: 'localhost',\n            use_appium: true\n          },\n          desiredCapabilities: {\n            browserName: null,\n            platformName: 'iOS',\n            'appium:deviceName': 'iPhone 13',\n            'appium:platformVersion': '15.0'\n          }\n        }\n      }\n    });\n    const runner = NightwatchClient.CliRunner({\n      config: 'ios_config.json',\n      env: 'simulator.ios',\n      workers: 4\n    }).setup();\n    assert.strictEqual(runner.isTestWorkersEnabled(), true);\n    assert.strictEqual(runner.parallelMode(), true);\n  });\n\n\n  it('disable parallelism when running tests on safari', function() {\n    class RunnerBaseMock extends RunnerBase {\n      static readTestSource(settings, argv) {\n        assert.strictEqual(settings.testWorkersEnabled, true);\n\n        return [\n          'test_file_1.js',\n          'test_file_2.js'\n        ];\n      }\n    }\n    mockery.registerMock('../runner.js', RunnerBaseMock);\n    const runner = NightwatchClient.CliRunner({\n      config: path.join(__dirname, '../../../extra/withsafari-concurrent.json'),\n      env: 'default'\n    }).setup();\n    assert.strictEqual(runner.isTestWorkersEnabled(), false);\n    assert.strictEqual(runner.parallelMode(), false);\n  });\n\n  it('disable parallelism when running tests on safari with --env chrome,safari', function() {\n    class RunnerBaseMock extends RunnerBase {\n      static readTestSource(settings, argv) {\n        assert.strictEqual(settings.testWorkersEnabled, true);\n\n        return [\n          'test_file_1.js',\n          'test_file_2.js'\n        ];\n      }\n    }\n    mockery.registerMock('../runner.js', RunnerBaseMock);\n    const runner = NightwatchClient.CliRunner({\n      config: path.join(__dirname, '../../../extra/withsafari-concurrent.json'),\n      env: ['default', 'chrome']\n    }).setup();\n    assert.strictEqual(runner.isTestWorkersEnabled(), false);\n    assert.strictEqual(runner.parallelMode(), false);\n  });\n\n  it('mobile config setup on with multiple envs - enable parallelism ', function() {\n    class RunnerBaseMock extends RunnerBase {\n      static readTestSource(settings, argv) {\n        assert.strictEqual(settings.testWorkersEnabled, true);\n\n        return [\n          'test_file_1.js',\n          'test_file_2.js'\n        ];\n      }\n    }\n    mockery.registerMock('../runner.js', RunnerBaseMock);\n    mockery.registerMock(path.join(process.cwd(), 'android_config.json'), {\n      test_settings: {\n        'default': {\n          desiredCapabilities: {\n            browserName: 'firefox'\n          }\n        },\n        'android.chrome': {\n          desiredCapabilities: {\n            avd: 'nightwatch-android-11',\n            browserName: 'chrome',\n            'goog:chromeOptions': {\n              androidPackage: 'com.android.chrome'\n            }\n          }\n        }\n      }\n    });\n    const runner = NightwatchClient.CliRunner({\n      config: 'android_config.json',\n      env: 'android.chrome,default'\n    }).setup();\n    assert.strictEqual(runner.isTestWorkersEnabled(), false);\n    assert.strictEqual(runner.parallelMode(), true);\n  });\n  \n\n  it('run worker threads with parallel_process_delay - worker threads', function() {\n    let startDelay = 0;\n    class RunnerBaseMock extends RunnerBase {\n      static readTestSource(settings, argv) {\n        assert.strictEqual(settings.testWorkersEnabled, true);\n\n        return [\n          'test_file_1.js',\n          'test_file_2.js'\n        ];\n      }\n    }\n\n    class WorkerTaskMock extends WorkerTask {\n      async runWorkerTask(colors, type) {\n        startDelay = this.startDelay;\n       \n        return new Promise((resolve, reject) => {\n          try {\n            assert.strictEqual(this.startDelay, 10);\n            resolve();\n          } catch (err) {\n            reject(err);\n          }\n        }, 10);\n      }\n    }\n    mockery.registerMock('./worker-task.js', WorkerTaskMock);\n    mockery.registerMock('../runner.js', RunnerBaseMock);\n\n    return NightwatchClient.runTests({\n      env: 'default',\n      config: path.join(__dirname, '../../../extra/withgeckodriver-concurrent.json')\n    }, settings({\n      parallel_process_delay: 100,\n      globals: {\n        reporter() {\n          assert.strictEqual(startDelay, 100);\n        }\n      },\n      use_child_process: false,\n      silent: false,\n      output: true,\n      output_folder: false\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/runner/cucumber-integration/testCliArgs.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst mockery = require('mockery');\nconst common = require('../../../common.js');\nconst CucumberRunner = common.require('runner/test-runners/cucumber.js');\n\ndescribe('Cucumber cli arguments', function(){\n  let cliArgs;\n\n  before(function() {\n    mockery.enable();\n    mockery.registerMock('@cucumber/cucumber/lib/cli/index', {\n      default: class CucumberCli {\n        constructor({argv, cwd, stdout}) {\n          cliArgs = argv;\n        }\n      }\n    });\n  });\n\n  after(function(){\n    mockery.deregisterAll();\n    mockery.disable();\n  });\n\n  it('Cucumber cli args --require-modules', function(){\n    const runner =  new CucumberRunner({test_runner: {\n      type: 'cucumber',\n      options: {}\n    }}, {'require-module': ['coffeescript/register', 'ts-node/register']});\n\n    runner.createTestSuite({\n      modules: [\n        path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')\n      ],\n      modulePath: [\n        path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')\n      ]\n    });\n\n    assert.ok(cliArgs.includes('--require-module'));\n    let index = cliArgs.indexOf('--require-module') + 1;\n\n    assert.strictEqual(cliArgs[index], 'coffeescript/register');\n    index =  cliArgs.indexOf('--require-module', index) + 1;\n    assert.strictEqual(cliArgs[index], 'ts-node/register');\n  });\n\n  it('Cucumber cli args', function(){\n    const runner =  new CucumberRunner({test_runner: {\n      type: 'cucumber',\n      options: {}\n    }}, {'no-strict': true, retries: 2, profile: 'local', 'fail-fast': true, parallel: 3, name: 'sample', 'retry-tag-filter': '@nightwatch'}, {});\n\n    runner.createTestSuite({\n      modules: [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')],\n      modulePath: [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')]\n    });\n\n    assert.strictEqual(cliArgs.length, 21);\n    assert.ok(cliArgs.includes('--name'));\n    assert.strictEqual(cliArgs[cliArgs.indexOf('--name') + 1], 'sample');\n    assert.ok(cliArgs.includes('--fail-fast'));\n    assert.ok(cliArgs.includes('--retry'));\n    assert.strictEqual(cliArgs[cliArgs.indexOf('--retry') + 1], 2);\n    assert.ok(cliArgs.includes('--retry-tag-filter'));\n    assert.strictEqual(cliArgs[cliArgs.indexOf('--retry-tag-filter') + 1], '@nightwatch');\n    assert.ok(cliArgs.includes('--profile'));\n    assert.strictEqual(cliArgs[cliArgs.indexOf('--profile') + 1], 'local');\n    assert.ok(cliArgs.includes('--no-strict'));\n    assert.ok(cliArgs.includes('--parallel'));\n    assert.strictEqual(cliArgs[cliArgs.indexOf('--parallel') + 1], 3);\n    assert.ok(cliArgs.includes('--require'));\n  });\n\n  it('Cucumber cli arg --dry-run', function(){\n    const runner = new CucumberRunner({\n      test_runner: {\n        type: 'cucumber',\n        options: {}\n      }\n    }, {\n      'dry-run': true\n    }, {});\n\n    runner.createTestSuite({\n      modules: [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')],\n      modulePath: [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')]\n    });\n\n    assert.ok(cliArgs.includes('--dry-run'));\n  });\n\n  it('Cucumber additional option --retries', function(){\n    const runner = new CucumberRunner({\n      test_runner: {\n        type: 'cucumber',\n        options: {\n          retries: 3\n        }\n      }\n    }, {}, {});\n\n    runner.createTestSuite({\n      modules: [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')],\n      modulePath: [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')]\n    });\n\n    assert.ok(cliArgs.includes('--retry'));\n  });\n\n  it('Cucumber additional options --retry and --format', function(){\n    const runner = new CucumberRunner({\n      test_runner: {\n        type: 'cucumber',\n        options: {\n          retries: 3,\n          format: '@cucumber/pretty-formatter'\n        }\n      }\n    }, {}, {});\n\n    runner.createTestSuite({\n      modules: [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')],\n      modulePath: [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')]\n    });\n\n    assert.ok(cliArgs.includes('--retry'));\n    assert.ok(cliArgs.includes('--format'));\n    assert.strictEqual(cliArgs[cliArgs.indexOf('--retry') + 1], 3);\n    assert.strictEqual(cliArgs[cliArgs.indexOf('--format') + 1], '@cucumber/pretty-formatter');\n  });\n\n  it('Cucumber cli arg --enable-esm', function(){\n    const runner = new CucumberRunner({\n      test_runner: {\n        type: 'cucumber',\n        options: {}\n      }\n    }, {\n      'enable-esm': true\n    }, {});\n\n    runner.createTestSuite({\n      modules: [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')],\n      modulePath: [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')]\n    });\n\n    assert.ok(cliArgs.includes('--import'));\n    assert.ok(!cliArgs.includes('--require'));\n  });\n\n  it('Cucumber options enable esm support', function(){\n    const runner = new CucumberRunner({\n      test_runner: {\n        type: 'cucumber',\n        options: {\n          enable_esm: true\n        }\n      }\n    }, {}, {});\n\n    const testModulePath = path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js');\n\n    runner.createTestSuite({\n      modules: [testModulePath],\n      modulePath: [testModulePath]\n    });\n\n    assert.ok(cliArgs.includes('--import'));\n    assert.ok(!cliArgs.includes('--require'));\n  });\n});\n"
  },
  {
    "path": "test/src/runner/cucumber-integration/testCucumberSampleTests.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst Globals = require('../../../lib/globals/commands.js');\nconst common = require('../../../common.js');\nconst MockServer = require('../../../lib/mockserver.js');\nconst {runTests} = common.require('index.js');\n\ndescribe('Cucumber integration', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => done());\n  });\n\n  afterEach(function(done) {\n    Globals.afterEach.call(this, done);\n  });\n\n  it('testCucumberSampleTests', function() {\n    const source = [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/parallelWithMultipleDefinition/testExpect.js'), path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')];\n\n    return runTests({\n      source,\n      tags: ['@pass'],\n      verbose: false,\n      config: path.join(__dirname, '../../../extra/cucumber-config.js')\n    }, {}).then(failures => {\n      assert.strictEqual(failures, false, 'Cucumber has test failures. Run with verbose to investigate.');\n    });\n  });\n\n  it('testCucumberSampleTests with failures', function() {\n    const source = [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testWithFailures.js')];\n\n    return runTests({\n      source,\n      tags: ['@fail'],\n      verbose: false,\n      config: path.join(__dirname, '../../../extra/cucumber-config.js')\n    }, {}).then(failures => {\n      assert.strictEqual(failures, true, 'Cucumber tests should have failed. Run with verbose to investigate.');\n    });\n  });\n\n  it('testCucumberSampleTests - chaining of commands failure', function() {\n    const source = [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/chainingCommands/testCommands.js')];\n\n    return runTests({\n      source,\n      tags: ['@fail'],\n      verbose: false,\n      config: path.join(__dirname, '../../../extra/cucumber-config.js')\n    }, {}).then(failures => {\n      assert.strictEqual(failures, true, 'Cucumber has test failures. Run with verbose to investigate.');\n    });\n  });\n\n\n  it('testCucumberSampleTests - use custom commands failure', function() {\n    const source = [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/customCommands/testCucumberWithCustomWait.js')];\n\n    return runTests({\n      source,\n      tags: ['@fail'],\n      verbose: false,\n      config: path.join(__dirname, '../../../extra/cucumber-config.js')\n    }, {})\n      .then(failures => {\n        assert.strictEqual(failures, true, 'Cucumber has test failures. Run with verbose to investigate.');\n      });\n  });\n});"
  },
  {
    "path": "test/src/runner/cucumber-integration/testCucumberWithBrowserstack.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst nock = require('nock');\nconst common = require('../../../common.js');\nconst {runTests} = common.require('index.js');\n\nxdescribe('Cucumber  Browserstack integration', function() {\n  \n  before(function(done) {\n    try {\n      nock.activate();\n    // eslint-disable-next-line no-empty\n    } catch (err) {\n    }\n   \n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session')\n      .reply(201, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: {\n          browserName: 'chrome'\n        }\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json')\n      .reply(200, []);\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session/1352110219202/url')\n      .reply(200, {\n        value: null\n      });\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session/1352110219202/elements')\n      .reply(200, {\n        status: 0,\n        sessionId: '1352110219202',\n        value: [{\n          'ELEMENT': '0'\n        }]\n      });\n\n    nock('https://hub-cloud.browserstack.com')\n      .delete('/wd/hub/session/1352110219202')\n      .reply(200, {\n        value: []\n      });\n\n    done();\n  });\n\n  after(function(done) {\n    nock.restore();\n    done();\n  });\n\n\n  it('testCucumberSampleTests - [Passed]', function() {\n   \n    nock('https://api.browserstack.com')\n      .put('/automate/sessions/1352110219202.json', body => body.status === 'passed')\n      .reply(200);\n\n    const source = [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testSample.js')];\n    \n    return runTests({\n      source,\n      tags: ['@pass'],\n      verbose: false,\n      config: path.join(__dirname, '../../../extra/cucumber-config.js'),\n      env: 'browserstack'\n    }, {}).then(failures => {\n      assert.strictEqual(failures, false, 'Cucumber has test failures. Run with verbose to investigate.');\n    });\n  });\n\n  it('testCucumberSampleTests with failures', function() {\n\n\n    nock('https://api.browserstack.com')\n      .put('/automate/sessions/1352110219202.json', body => body.status === 'failed')\n      .reply(200);\n    \n    const source = [path.join(__dirname, '../../../cucumber-integration-tests/sample_cucumber_tests/integration/testWithFailures.js')];\n    \n    return runTests({\n      source,\n      env: 'browserstack',\n      tags: ['@fail'],\n      verbose: false,\n      config: path.join(__dirname, '../../../extra/cucumber-config.js')\n    }, {}).then(failures => {\n      assert.strictEqual(failures, true, 'Cucumber tests should have failed. Run with verbose to investigate.');\n    });\n  });\n});\n\n"
  },
  {
    "path": "test/src/runner/mocha/testMochaRunnerAsync.js",
    "content": "const common = require('../../../common.js');\nconst path = require('path');\nconst assert = require('assert');\nconst Globals = require('../../../lib/globals/commands.js');\nconst MockServer = require('../../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('test Mocha Runner async', function() {\n  const originalExit = process.exit;\n  this.timeout(10000);\n\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.exit = originalExit;\n    Globals.afterEach.call(this, done);\n  });\n\n  it('test run mocha samples with async and failures', function() {\n    const globals = {\n      test_calls: 0,\n      retryAssertionTimeout: 0\n    };\n\n    return runTests(path.join(__dirname, '../../../mochatests/async/'), settings({\n      globals,\n      test_runner: {\n        type: 'mocha',\n        options: {\n          timeout: 5000\n        }\n      },\n      output: false,\n      silent: false\n    })).catch(err => {\n      return err;\n    }).then((err) => {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(globals.test_calls, 12);\n      assert.strictEqual(err.failures, 2);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/runner/mocha/testMochaRunnerIntegration.js",
    "content": "const common = require('../../../common.js');\nconst path = require('path');\nconst assert = require('assert');\nconst Globals = require('../../../lib/globals/commands.js');\nconst MockServer = require('../../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('test Mocha Runner integration', function() {\n  this.timeout(10000);\n\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    Globals.afterEach.call(this, done);\n  });\n\n  it('testRunMochaSampleTests', function() {\n    const globals = {\n      test_calls: 0,\n      retryAssertionTimeout: 0\n    };\n\n    let testsPath = path.join(__dirname, '../../../mochatests/integration');\n    let error;\n\n    return runTests(testsPath, settings({\n      globals,\n      test_runner: {\n        type: 'mocha',\n        options: {\n          timeout: 5000\n        }\n      },\n      output: false,\n      silent: false\n    })).catch(err => {\n      error = err;\n    }).then((err) => {\n      assert.strictEqual(globals.waitForConditionTimeout, 1100);\n      assert.strictEqual(globals.retryAssertionTimeout, 1100);\n      assert.strictEqual(globals.waitForConditionPollInterval, 100);\n\n      assert.strictEqual(globals.test_calls, 17);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/runner/testEventReporter.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst mockery = require('mockery');\nconst rimraf = require('rimraf');\n\nconst common = require('../../common.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\nconst {mkpath} = common.require('utils');\n\nconst MockServer = require('../../lib/mockserver.js');\n\ndescribe('testNightwatchEventReporter', function() {\n\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => done());\n  });\n\n  beforeEach(function(done) {\n    mkpath('output', function(err) {\n      if (err) {\n        return done(err);\n      }\n      mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n      done();\n    });\n  });\n\n\n  afterEach(function(done) {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n    rimraf('output', done);\n  });\n\n\n  after(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('Check reporter output on real time event', async function () {\n    let possibleError = null;\n    const testsPath = [path.join(__dirname, '../../sampletests/before-after/sampleWithBeforeAndAfterNoCallback.js')];\n\n    const eventExecuted = {\n      TestSuiteStarted: false,\n      TestSuiteFinished: false,\n      BeforeStarted: false,\n      BeforeFinished: false,\n      TestRunStarted: false,\n      TestRunFinished: false,\n      AfterStarted: false,\n      AfterFinished: false,\n      LogCreated: false,\n      AfterEachFinished: false,\n      AfterEachStarted: false\n    };\n\n    try {\n      await runTests({\n        source: testsPath\n      },\n      settings({\n        output_folder: 'output',\n        globals: {\n          waitForConditionPollInterval: 20,\n          waitForConditionTimeout: 50,\n          retryAssertionTimeout: 50,\n          registerEventHandlers: function(eventBroadcaster) {\n            eventBroadcaster.on('TestSuiteStarted', (args) => {\n              assert.deepStrictEqual(Object.keys(args), ['envelope', 'metadata']);\n              eventExecuted.TestSuiteStarted = true;\n            });\n            \n            eventBroadcaster.on('TestSuiteFinished', (args) => {\n              assert.deepStrictEqual(Object.keys(args), ['envelope', 'metadata']);\n              eventExecuted.TestSuiteFinished = true;\n            });\n            \n            eventBroadcaster.on('BeforeStarted', (args) => {\n              assert.deepStrictEqual(Object.keys(args), ['envelope', 'metadata']);\n              eventExecuted.BeforeStarted = true;\n            });\n            \n            eventBroadcaster.on('BeforeFinished', (args) => {\n              assert.deepStrictEqual(Object.keys(args), ['envelope', 'metadata']);\n              assert.ok(Object.prototype.hasOwnProperty.call(args['envelope'], '__before_hook'));\n              eventExecuted.BeforeFinished = true;\n            });\n            \n            eventBroadcaster.on('TestRunStarted', (args) => {\n              assert.deepStrictEqual(Object.keys(args), ['envelope', 'metadata', 'testcase', 'settings', 'testCaseData']);\n              eventExecuted.TestRunStarted = true;\n            });\n            \n            eventBroadcaster.on('TestRunFinished', (args) => {\n              assert.deepStrictEqual(Object.keys(args), ['envelope', 'metadata', 'testcase', 'settings', 'testCaseData']);\n              eventExecuted.TestRunFinished = true;\n            });\n            \n            eventBroadcaster.on('AfterStarted', (args) => {\n              assert.deepStrictEqual(Object.keys(args), ['envelope', 'metadata']);\n              eventExecuted.AfterStarted = true;\n            });\n            \n            eventBroadcaster.on('AfterFinished', (args) => {\n              assert.deepStrictEqual(Object.keys(args), ['envelope', 'metadata']);\n              eventExecuted.AfterFinished = true;\n            });\n            \n            eventBroadcaster.on('LogCreated', (args) => {\n              assert.deepStrictEqual(Object.keys(args), ['httpOutput']);\n              eventExecuted.LogCreated = true;\n            });            \n          }\n        },\n        silent: true,\n        output: false\n      }));\n\n      assert.strictEqual(eventExecuted.AfterFinished, true);\n      assert.strictEqual(eventExecuted.AfterStarted, true);\n      assert.strictEqual(eventExecuted.BeforeFinished, true);\n      assert.strictEqual(eventExecuted.BeforeStarted, true);\n      assert.strictEqual(eventExecuted.LogCreated, true);\n      assert.strictEqual(eventExecuted.TestRunFinished, true);\n      assert.strictEqual(eventExecuted.TestRunStarted, true);\n      assert.strictEqual(eventExecuted.AfterEachFinished, false);\n      assert.strictEqual(eventExecuted.AfterEachStarted, false);\n      assert.strictEqual(eventExecuted.TestSuiteFinished, true);\n      assert.strictEqual(eventExecuted.TestSuiteStarted, true);\n    } catch (error) {\n      possibleError = error;\n    }\n    \n    assert.strictEqual(possibleError, null);\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testInspectorExtension.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\nconst mockery = require('mockery');\n\ndescribe('testInspectorExtension', function () {\n\n  beforeEach(function (done) {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  \n    MockServer.addMock({\n      url: '/wd/hub/session/13521-10219-202/elements',\n      method: 'POST',\n      postdata: JSON.stringify({using: 'css selector', value: '#weblogin'}),\n      response: {\n        value: [{\n          'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n        }]\n      }\n    }, false);\n  \n    MockServer.addMock({\n      url: '/wd/hub/session/13521-10219-202/url',\n      method: 'POST',\n      postdata: JSON.stringify({\n        url: 'http://localhost'\n      }),\n      response: {\n        value: null\n      }\n    }, false);\n  \n    MockServer.addMock({\n      url: '/wd/hub/session/13521-10219-202',\n      method: 'DELETE',\n      response: {\n        value: null\n      }\n    }, false);\n  \n    mockery.registerMock('@nightwatch/nightwatch-inspector', {\n      crxfile: 'mocked crxfile'\n    });\n\n    mockery.registerMock('./websocket-server', class {\n      initSocket() {};\n  \n      closeSocket() {};\n    });\n  });\n\n  afterEach(function (done) {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n\n    CommandGlobals.afterEach.call(this, function () {\n      Object.keys(require.cache).forEach(function (module) {\n        delete require.cache[module];\n      });\n\n      done();\n    });\n  });\n\n  it('extension should attach in debug mode', function() {\n    MockServer.addMock({\n      url: '/wd/hub/session',\n      statusCode: 200,\n      method: 'POST',\n      postdata: JSON.stringify({\n        capabilities: {\n          firstMatch: [{}],\n          alwaysMatch: {\n            browserName: 'chrome',\n            'goog:chromeOptions': {\n              extensions: ['mocked crxfile'],\n              args: ['--auto-open-devtools-for-tabs']\n            }\n          }\n        }\n      }),\n      response: JSON.stringify({\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            acceptInsecureCerts: false,\n            browserName: 'chrome',\n            browserVersion: '65.0.1'\n          }\n        }\n      })\n    }, false);\n\n    const testsPath = path.join(__dirname, '../../sampletests/simple/test/sample.js');\n    let desiredCapabilities;\n\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      beforeEach: function(client, cb) {\n        desiredCapabilities = client.desiredCapabilities;\n        cb();\n      },\n      reporter(results, cb) {\n        assert.strictEqual(desiredCapabilities.browserName, 'chrome');\n        assert.ok('goog:chromeOptions' in desiredCapabilities);\n        assert.deepStrictEqual(desiredCapabilities['goog:chromeOptions'].extensions, ['mocked crxfile']);\n        assert.deepStrictEqual(desiredCapabilities['goog:chromeOptions'].args, ['--auto-open-devtools-for-tabs']);\n        assert.strictEqual(this.settings.parallel_mode, false);\n        assert.strictEqual(results.passed, 2);\n        assert.strictEqual(results.errors, 0);\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath],\n      debug: true\n    }, settings({\n      globals,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    }));\n  });\n\n  it('extension should not attach if debug mode is false', function() {\n    MockServer.addMock({\n      url: '/wd/hub/session',\n      statusCode: 200,\n      method: 'POST',\n      postdata: JSON.stringify({\n        capabilities: {\n          firstMatch: [{}],\n          alwaysMatch: {\n            browserName: 'chrome',\n            'goog:chromeOptions': {}\n          }\n        }\n      }),\n      response: JSON.stringify({\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            acceptInsecureCerts: false,\n            browserName: 'chrome',\n            browserVersion: '65.0.1'\n          }\n        }\n      })\n    }, false);\n\n    const testsPath = path.join(__dirname, '../../sampletests/simple/test/sample.js');\n    let desiredCapabilities;\n\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      beforeEach: function(client, cb) {\n        desiredCapabilities = client.desiredCapabilities;\n        cb();\n      },\n      reporter(results, cb) {\n        assert.strictEqual(desiredCapabilities.browserName, 'chrome');\n        assert.strictEqual('goog:chromeOptions' in desiredCapabilities, false);\n        assert.strictEqual(this.settings.parallel_mode, false);\n        assert.strictEqual(results.passed, 2);\n        assert.strictEqual(results.errors, 0);\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      globals,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    }));\n  });\n\n  it('websocket should be closed after execution', function() {\n    let closeSocketCalled = false;\n\n    mockery.registerMock('./websocket-server.js', class {\n      initSocket() {};\n\n      closeSocket() {\n        closeSocketCalled = true;\n      };\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session',\n      statusCode: 200,\n      method: 'POST',\n      postdata: JSON.stringify({\n        capabilities: {\n          firstMatch: [{}],\n          alwaysMatch: {\n            browserName: 'chrome',\n            'goog:chromeOptions': {\n              extensions: ['mocked crxfile'],\n              args: ['--auto-open-devtools-for-tabs']\n            }\n          }\n        }\n      }),\n      response: JSON.stringify({\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            acceptInsecureCerts: false,\n            browserName: 'chrome',\n            browserVersion: '65.0.1'\n          }\n        }\n      })\n    }, false);\n\n    const testsPath = path.join(__dirname, '../../sampletests/simple/test/sample.js');\n    let desiredCapabilities;\n\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      beforeEach: function(client, cb) {\n        desiredCapabilities = client.desiredCapabilities;\n        cb();\n      },\n      reporter(results, cb) {\n        assert.strictEqual(desiredCapabilities.browserName, 'chrome');\n        assert.ok('goog:chromeOptions' in desiredCapabilities);\n        assert.deepStrictEqual(desiredCapabilities['goog:chromeOptions'].extensions, ['mocked crxfile']);\n        assert.deepStrictEqual(desiredCapabilities['goog:chromeOptions'].args, ['--auto-open-devtools-for-tabs']);\n        assert.strictEqual(this.settings.parallel_mode, false);\n        assert.strictEqual(results.passed, 2);\n        assert.strictEqual(results.errors, 0);\n        assert.ok(closeSocketCalled);\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath],\n      debug: true\n    }, settings({\n      globals,\n      output: false,\n      desiredCapabilities: {\n        browserName: 'chrome'\n      }\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testReporter.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst mockery = require('mockery');\nconst rimraf = require('rimraf');\n\nconst common = require('../../common.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\nconst {mkpath} = common.require('utils');\nconst {readFilePromise, readDirPromise} = require('../../lib/utils.js');\n\nconst MockServer = require('../../lib/mockserver.js');\nconst Reporter = common.require('reporter/global-reporter.js');\n\ndescribe('testReporter', function() {\n\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => done());\n  });\n\n  beforeEach(function(done) {\n    mkpath('output', function(err) {\n      if (err) {\n        return done(err);\n      }\n      mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n      done();\n    });\n  });\n\n\n  afterEach(function(done) {\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n    rimraf('output', done);\n  });\n\n\n  after(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('test with unknown reporter', function() {\n    const reporter = new Reporter('unknown', {\n      globals: {\n        reporter(results, done) {\n          done();\n        }\n      },\n      output_folder: 'output'\n    });\n\n    return reporter.loadReporter()\n      .catch(err => {\n        assert.ok(err instanceof Error);\n        assert.strictEqual(err.message, 'The custom reporter \"unknown\" cannot be resolved.');\n      });\n  });\n\n  it('test with invalid reporter', function() {\n    const custom_reporter = path.join(__dirname, '../../extra/reporter/notvalid.js');\n    const reporter = new Reporter(custom_reporter, {\n      globals: {\n        reporter(results, done) {\n          done();\n        }\n      },\n      output_folder: 'output'\n    });\n\n    return reporter.loadReporter()\n      .catch(err => {\n        assert.strictEqual(err.message, `The custom reporter \"${custom_reporter}\" must have a public \".write(results, options, [callback])\" method defined which should return a Promise.`);\n      });\n  });\n\n  it('test with valid reporter file name', function() {\n\n    const reporter = new Reporter(path.join(__dirname, '../../extra/reporter/custom.js'), {\n      globals: {\n        reporter(results, done) {\n          done();\n        }\n      },\n      output_folder: 'output'\n    });\n\n    reporter.writeReport = function (reporter, globalResults) {\n      Promise.resolve();\n    };\n\n    return reporter.save().then(function(result) {\n      assert.ok(Array.isArray(result));\n      assert.strictEqual(result.length, 2);\n    });\n  });\n\n  it('test with valid reporter from NPM', function() {\n    mockery.registerMock('nightwatch_reporter', {\n      async write(results, options) {\n\n        return 'reporter_output';\n      }\n    });\n\n    const reporter = new Reporter('nightwatch_reporter', {\n      globals: {\n        reporter(results, done) {\n          done();\n        }\n      },\n      output_folder: 'output',\n      reporter_options: {}\n    });\n\n    return reporter.writeReportToFile().then(function(result) {\n      assert.deepStrictEqual(result, ['reporter_output']);\n    });\n  });\n\n  it('test run tests with multiple reporters - html + junit', async function () {\n    let possibleError = null;\n    const testsPath = [path.join(__dirname, '../../sampletests/simple/test/sample.js')];\n\n    try {\n      await runTests({\n        source: testsPath,\n        reporter: ['html', 'junit']\n      },\n      settings({\n        output_folder: 'output',\n        globals: {\n          waitForConditionPollInterval: 20,\n          waitForConditionTimeout: 50,\n          retryAssertionTimeout: 50,\n          reporter: function () {}\n        },\n        output: false\n      }));\n\n      await readFilePromise(`output${path.sep}FIREFOX_TEST_firefox__sample.xml`);\n      await readDirPromise(`output${path.sep}nightwatch-html-report`);\n    } catch (error) {\n      possibleError = error;\n    }\n\n    assert.strictEqual(possibleError, null);\n  });\n\n  it('test run tests with default reporters', async function () {\n    let possibleError = null;\n    const testsPath = [path.join(__dirname, '../../sampletests/simple/test/sample.js')];\n\n    try {\n      await runTests({\n\n        source: testsPath\n      },\n      settings({\n        output_folder: 'output',\n        globals: {\n          waitForConditionPollInterval: 20,\n          waitForConditionTimeout: 50,\n          retryAssertionTimeout: 50,\n          reporter: function () {}\n        },\n        silent: true,\n        output: false\n      }));\n\n      await readFilePromise(`output${path.sep}FIREFOX_TEST_firefox__sample.xml`);\n      await readFilePromise(`output${path.sep}FIREFOX_TEST_firefox__sample.json`);\n      await readDirPromise(`output${path.sep}nightwatch-html-report`);\n    } catch (error) {\n      possibleError = error;\n    }\n\n    assert.strictEqual(possibleError, null);\n  });\n\n  it('test run tests with default reporters - open the html report', async function () {\n    let htmlFile;\n\n    mockery.registerMock('open', function(filename) {\n      htmlFile = filename;\n\n      return Promise.resolve();\n    });\n\n    let possibleError = null;\n    const testsPath = [path.join(__dirname, '../../sampletests/simple/test/sample.js')];\n\n    try {\n      await runTests({\n        source: testsPath,\n        open: true\n      },\n      settings({\n        output_folder: 'output',\n        globals: {\n          waitForConditionPollInterval: 20,\n          waitForConditionTimeout: 50,\n          retryAssertionTimeout: 50,\n          reporter: function () {}\n        },\n        silent: true,\n        output: false\n      }));\n\n      await readFilePromise(`output${path.sep}FIREFOX_TEST_firefox__sample.xml`);\n      await readFilePromise(`output${path.sep}FIREFOX_TEST_firefox__sample.json`);\n      await readDirPromise(`output${path.sep}nightwatch-html-report`);\n    } catch (error) {\n      possibleError = error;\n    }\n\n    assert.strictEqual(possibleError, null);\n    assert.strictEqual(htmlFile, `output${path.sep}nightwatch-html-report${path.sep}index.html`);\n\n  });\n\n  it('Check reporter output for varaious properties', async function () {\n    let possibleError = null;\n    const testsPath = [path.join(__dirname, '../../sampletests/simple/test/sample.js')];\n\n    try {\n      await runTests({\n        source: testsPath\n      },\n      settings({\n        output_folder: 'output',\n        globals: {\n          waitForConditionPollInterval: 20,\n          waitForConditionTimeout: 50,\n          retryAssertionTimeout: 50,\n          reporter: function (results) {\n            // check for results properties\n            assert.ok(Object.keys(results).includes('elapsedTime'));\n            assert.ok(Object.keys(results).includes('startTimestamp'));\n            assert.ok(Object.keys(results).includes('endTimestamp'));\n\n            const module = results.modules['sample'];\n            // check for module properties\n            assert.ok(Object.keys(module).includes('sessionCapabilities'));\n            assert.ok(Object.keys(module).includes('sessionId'));\n            assert.ok(Object.keys(module).includes('projectName'));\n            assert.ok(Object.keys(module).includes('buildName'));\n            assert.ok(Object.keys(module).includes('startTimestamp'));\n            assert.ok(Object.keys(module).includes('endTimestamp'));\n            assert.ok(Object.keys(module).includes('host'));\n            assert.ok(Object.keys(module).includes('name'));\n            assert.ok(Object.keys(module).includes('tags'));\n\n            // check for individual test properties\n            const test = module.completed['demoTest'];\n            assert.ok(Object.keys(test).includes('status'));\n            assert.ok(Object.keys(test).includes('startTimestamp'));\n            assert.ok(Object.keys(test).includes('endTimestamp'));\n            assert.strictEqual(test.status, 'pass');\n          }\n        },\n        silent: true,\n        output: false\n      }));\n\n    } catch (error) {\n      possibleError = error;\n    }\n    assert.strictEqual(possibleError, null);\n\n  });\n\n  it('Check reporter output for completedSections', async function () {\n    let possibleError = null;\n    const testsPath = [path.join(__dirname, '../../sampletests/sampleforreport/sample.js')];\n\n    try {\n      await runTests({\n        source: testsPath\n      },\n      settings({\n        output_folder: 'output',\n        globals: {\n          waitForConditionPollInterval: 20,\n          waitForConditionTimeout: 50,\n          retryAssertionTimeout: 50,\n          reporter: function (results) {\n            const module = results.modules['sample'];\n\n            assert.ok(Object.keys(module).includes('completedSections'));\n\n            const completedSections = module['completedSections'];\n\n            // check module properties all for hooks\n            const hooks = ['__after_hook', '__before_hook', '__global_afterEach_hook', '__global_beforeEach_hook', 'demoTest'];\n\n            hooks.forEach(hook => {\n              assert.ok(Object.keys(completedSections).includes(hook));\n\n              const sectionData = completedSections[hook];\n              assert.ok(Object.keys(sectionData).includes('startTimestamp'));\n              assert.ok(Object.keys(sectionData).includes('endTimestamp'));\n              assert.ok(Object.keys(sectionData).includes('httpOutput'));\n              assert.strictEqual(sectionData['status'], 'pass');\n            });\n            \n            assert.strictEqual(completedSections['__after_hook']['commands'].length, 1);\n            assert.strictEqual(completedSections['__after_hook']['commands'][0].name, 'end');\n\n            // check for individual test properties\n            const test = completedSections['demoTest'];\n            assert.ok(Object.keys(test).includes('status'));\n            assert.ok(Object.keys(test).includes('commands'));\n\n            assert.strictEqual(test.status, 'pass');\n            assert.strictEqual(test.passed, 3);\n            assert.strictEqual(test.failed, 0);\n            assert.strictEqual(test.errors, 0);\n\n            assert.strictEqual(test.commands.length, 4);\n            assert.strictEqual(test.commands[0].name, 'assert.equal');\n            assert.strictEqual(test.commands[1].name, 'url');\n            assert.strictEqual(test.commands[2].name, 'assert.elementPresent');\n            assert.strictEqual(test.commands[3].name, 'assert.equal');\n\n            const command = test.commands[1];\n            assert.ok(Object.keys(command).includes('startTime'));\n            assert.ok(Object.keys(command).includes('endTime'));\n            assert.ok(Object.keys(command).includes('elapsedTime'));\n            assert.ok(Object.keys(command).includes('result'));\n            assert.deepEqual(command.args, ['\"http://localhost\"']);\n            assert.strictEqual(command.status, 'pass');\n\n            const beforeEach = test.beforeEach;\n            assert.strictEqual(beforeEach.commands.length, 0);\n            assert.strictEqual(beforeEach.status, 'pass');\n\n            const testcase = test.testcase;\n            assert.strictEqual(testcase.commands.length, 3);\n            assert.deepStrictEqual(testcase.commands.map(comm => comm.name), ['assert.equal', 'url', 'assert.elementPresent']);\n            assert.strictEqual(testcase.status, 'pass');\n            assert.strictEqual(testcase.passed, 2);\n            assert.strictEqual(testcase.failed, 0);\n            assert.strictEqual(testcase.errors, 0);\n\n            const afterEach = test.afterEach;\n            assert.strictEqual(afterEach.commands.length, 1);\n            assert.strictEqual(afterEach.commands[0].name, 'assert.equal');\n            assert.strictEqual(afterEach.status, 'pass');\n            assert.strictEqual(afterEach.passed, 1);\n            assert.strictEqual(afterEach.failed, 0);\n            assert.strictEqual(afterEach.errors, 0);\n          }\n        },\n        silent: true,\n        output: false\n      }));\n\n    } catch (error) {\n      possibleError = error;\n    }\n    assert.strictEqual(possibleError, null);\n\n  });\n\n  it('Check reporter output for completedSections with failures', async function () {\n    let possibleError = null;\n    const testsPath = [path.join(__dirname, '../../sampletests/sampleforreport/sampleWithFailure.js')];\n\n    try {\n      await runTests({\n        source: testsPath\n      },\n      settings({\n        output_folder: 'output',\n        globals: {\n          waitForConditionPollInterval: 20,\n          waitForConditionTimeout: 50,\n          retryAssertionTimeout: 50,\n          reporter: function (results) {\n            const module = results.modules['sampleWithFailure'];\n\n            assert.ok(Object.keys(module).includes('completedSections'));\n\n            const completedSections = module['completedSections'];\n\n            // check module properties all for hooks\n            const hooks = ['__after_hook', '__before_hook', '__global_afterEach_hook', '__global_beforeEach_hook', 'demoTest'];\n\n            hooks.forEach(hook => {\n              assert.ok(Object.keys(completedSections).includes(hook));\n\n              const sectionData = completedSections[hook];\n              assert.ok(Object.keys(sectionData).includes('startTimestamp'));\n              assert.ok(Object.keys(sectionData).includes('endTimestamp'));\n              assert.ok(Object.keys(sectionData).includes('httpOutput'));\n            });\n            \n            const afterHook = completedSections['__after_hook'];\n            assert.strictEqual(afterHook['commands'].length, 2);\n            assert.strictEqual(afterHook['commands'][0].name, 'assert.equal');\n            assert.strictEqual(afterHook['commands'][1].name, 'end');\n            assert.strictEqual(afterHook.status, 'pass');\n            assert.strictEqual(afterHook.passed, 1);\n            assert.strictEqual(afterHook.failed, 0);\n            assert.strictEqual(afterHook.errors, 0);\n\n            // check for individual test properties\n            const test = completedSections['demoTest'];\n            assert.ok(Object.keys(test).includes('status'));\n            assert.ok(Object.keys(test).includes('commands'));\n\n            assert.strictEqual(test.status, 'fail');\n            assert.strictEqual(test.passed, 2);\n            assert.strictEqual(test.failed, 1);\n            assert.strictEqual(test.errors, 0);\n\n            assert.strictEqual(test.commands.length, 4);\n            assert.strictEqual(test.commands[0].name, 'assert.equal');\n            assert.strictEqual(test.commands[1].name, 'url');\n            assert.strictEqual(test.commands[2].name, 'assert.elementPresent');\n            assert.strictEqual(test.commands[3].name, 'assert.equal');\n\n            const command = test.commands[1];\n            assert.ok(Object.keys(command).includes('startTime'));\n            assert.ok(Object.keys(command).includes('endTime'));\n            assert.ok(Object.keys(command).includes('elapsedTime'));\n            assert.ok(Object.keys(command).includes('result'));\n            assert.deepEqual(command.args, ['\"http://localhost\"']);\n            assert.strictEqual(command.status, 'pass');\n\n            const beforeEach = test.beforeEach;\n            assert.strictEqual(beforeEach.commands.length, 0);\n            assert.strictEqual(beforeEach.status, 'pass');\n\n            const testcase = test.testcase;\n            assert.strictEqual(testcase.commands.length, 3);\n            assert.deepStrictEqual(testcase.commands.map(comm => comm.name), ['assert.equal', 'url', 'assert.elementPresent']);\n            assert.strictEqual(testcase.status, 'fail');\n            assert.strictEqual(testcase.passed, 1);\n            assert.strictEqual(testcase.failed, 1);\n            assert.strictEqual(testcase.errors, 0);\n\n            const afterEach = test.afterEach;\n            assert.strictEqual(afterEach.commands.length, 1);\n            assert.strictEqual(afterEach.commands[0].name, 'assert.equal');\n            assert.strictEqual(afterEach.status, 'pass');\n            assert.strictEqual(afterEach.passed, 1);\n            assert.strictEqual(afterEach.failed, 0);\n            assert.strictEqual(afterEach.errors, 0);\n          }\n        },\n        silent: true,\n        output: false\n      }));\n\n    } catch (error) {\n      possibleError = error;\n    }\n    assert.strictEqual(possibleError, null);\n\n  });\n\n  it('check reporter output with appended results', async function() {\n    let possibleError = null;\n    const testPath = [path.join(__dirname, '../../sampletests/appendtestresult/sampleWithAppendResults.js')];\n    const customCommands = [path.join(__dirname, '../../extra/commands')];\n\n    try {\n      await runTests({\n        source: testPath\n      }, settings({\n        custom_commands_path: customCommands,\n        globals: {\n          waitForConditionPollInterval: 20,\n          waitForConditionTimeout: 50,\n          retryAssertionTimeout: 50,\n          reporter: function (results) {\n            const module = results.modules['sampleWithAppendResults'];\n            \n            assert.ok(Object.keys(module).includes('completedSections'));\n            const completedSections = module['completedSections'];\n            assert.ok(Object.keys(completedSections).includes('demoTest'));\n\n            const test = completedSections['demoTest'];\n            assert.ok(Object.keys(test).includes('customReport'));\n            assert.deepStrictEqual(test.customReport, {success: true});\n          }\n        },\n        silent: true,\n        output: false\n      }));\n    } catch (err) {\n      possibleError = err;\n    }\n    assert.strictEqual(possibleError, null);\n  });\n\n  it('test with multiple reporters', function() {\n    mockery.registerMock('nightwatch_reporter', {\n      async write(_results, _options) {\n\n        return 'nightwatch_reporter_output';\n      }\n    });\n    mockery.registerMock('html_reporter', {\n      async write(_results, _options) {\n\n        return 'html_reporter_output';\n      }\n    });\n\n    const reporter = new Reporter('nightwatch_reporter,html_reporter', {\n      globals: {\n        reporter(_results, done) {\n          done();\n        }\n      },\n      output_folder: 'output',\n      reporter_options: {}\n    });\n\n    return reporter.writeReportToFile().then(function(result) {\n      assert.deepStrictEqual(result, ['nightwatch_reporter_output', 'html_reporter_output']);\n    });\n  });\n\n  it('test to check retry data logging', function() {\n    this.timeout(100000);\n\n    const testsPath = path.join(__dirname, '../../sampletests/withfailures');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.ok('sample' in results.modules);\n        assert.ok('completedSections' in results.modules['sample']);\n        assert.ok('demoTest' in results.modules['sample']['completedSections']);\n        assert.ok('retryTestData' in results.modules['sample']['completedSections']['demoTest']);\n        assert.ok(results.modules['sample']['completedSections']['demoTest']['retryTestData'].length <= 3);\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests({\n      retries: 3,\n      _source: [testsPath]\n    }, settings({\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRerunFunctionality.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRerun', function () {\n  beforeEach(function (done) {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n    \n    this.server = MockServer.init();\n    \n    this.server.on('listening', () => {\n      done();\n    });\n  });\n    \n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, function () {\n      Object.keys(require.cache).forEach(function (module) {\n        delete require.cache[module];\n      });\n    \n      done();\n    });\n  });\n\n  it('Rerun with --rerun-failed cli argument without setting env variable for json reporter', function () {\n\n    return runTests({\n      'rerun-failed': true\n    }, settings({\n      output: false\n    })).catch(err => {\n      return err;\n    }).then(err => {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.message, 'Unable to find the Json reporter file to rerun failed tests');\n      assert.strictEqual(err.detailedErr, 'Configure the environment variable NIGHTWATCH_RERUN_REPORT_FILE with Json reporter file path');\n    });\n  });\n\n  it('Rerun with env varaible without setting env variable for json reporter', function () {\n    process.env.NIGHTWATCH_RERUN_FAILED = 'true';\n\n    return runTests({\n      'rerun-failed': true\n    }, settings({\n      output: false\n    })).catch(err => {\n      return err;\n    }).then(err => {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.message, 'Unable to find the Json reporter file to rerun failed tests');\n      assert.strictEqual(err.detailedErr, 'Configure the environment variable NIGHTWATCH_RERUN_REPORT_FILE with Json reporter file path');\n\n      delete process.env.NIGHTWATCH_RERUN_FAILED;\n    });\n  });\n\n  it('Rerun with env varaible set and with setting env variable for json reporter', function () {\n    process.env.NIGHTWATCH_RERUN_FAILED = 'true';\n    process.env.NIGHTWATCH_RERUN_REPORT_FILE = path.join(__dirname, '../../extra/minimalJsonReporter.json');\n\n    return runTests({\n    }, settings({\n      output: false,\n      globals: {\n        reporter(results) {\n          assert.strictEqual(Object.keys(results.modules).length, 1);\n          assert.strictEqual(results.assertions, 2);\n        }\n      }\n    })).then(err => {\n      assert.strictEqual(err, false);\n\n      delete process.env.NIGHTWATCH_RERUN_FAILED;\n      delete process.env.NIGHTWATCH_RERUN_REPORT_FILE;\n    });\n  });\n\n  it('Rerun with cli flag and with setting env variable for json reporter', function () {\n    process.env.NIGHTWATCH_RERUN_REPORT_FILE = path.join(__dirname, '../../extra/minimalJsonReporter.json');\n\n    return runTests({\n      'rerun-failed': true\n    }, settings({\n      output: false,\n      globals: {\n        reporter(results) {\n          assert.strictEqual(Object.keys(results.modules).length, 1);\n          assert.strictEqual(results.assertions, 2);\n        }\n      }\n    })).then(err => {\n      assert.strictEqual(err, false);\n      delete process.env.NIGHTWATCH_RERUN_REPORT_FILE;\n    });\n  });\n\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunBrowserstackTransport.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst nock = require('nock');\nconst common = require('../../common.js');\n\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunBrowserstackTransport', function() {\n  let statusSetNockCalled = 0;\n  let sessionNockCalled = 0;\n\n  before(function(done) {\n    try {\n      nock.activate();\n      // eslint-disable-next-line no-empty\n    } catch (err) {}\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session')\n      .times(2)\n      .reply(201, (uri, requestBody) => {\n        assert.ok(requestBody.capabilities.alwaysMatch['bstack:options'].sessionName, 'session request should contain session Name');\n        \n        return {\n          status: 0,\n          sessionId: '1352110219202',\n          value: {\n            browserName: 'chrome'\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/builds.json?status=running')\n      .times(2)\n      .reply(200, []);\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session/1352110219202/url')\n      .times(2)\n      .reply(200, {\n        value: null\n      });\n\n    nock('https://hub-cloud.browserstack.com')\n      .post('/wd/hub/session/1352110219202/elements')\n      .times(2)\n      .times(5)\n      .reply(200, {\n        value: []\n      });\n\n    nock('https://hub-cloud.browserstack.com')\n      .delete('/wd/hub/session/1352110219202')\n      .times(2)\n      .reply(200, {\n        value: []\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/sessions/1352110219202.json')\n      .reply(200, function() {\n        sessionNockCalled++;\n\n        return {\n          automation_session: {\n            status: 'failed'\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .get('/automate/sessions/1352110219202.json')\n      .reply(200, function() {\n        sessionNockCalled++;\n\n        return {\n          automation_session: {\n            status: 'done'\n          }\n        };\n      });\n\n    nock('https://api.browserstack.com')\n      .put('/automate/sessions/1352110219202.json', {\n        status: 'failed',\n        reason: /^NightwatchAssertError: Testing if element <#weblogin> is present in 10ms/\n      })\n      .times(1)\n      .reply(200, function() {\n        statusSetNockCalled++;\n\n        return {};\n      });\n\n    done();\n  });\n\n  after(function(done) {\n    nock.restore();\n    done();\n  });\n\n  it('run with error', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withfailures/');\n\n    return runTests({\n      suiteRetries: 1,\n      source: testsPath\n    }, settings({\n      output: true,\n      silent: false,\n      webdriver: {\n        host: 'hub-cloud.browserstack.com',\n        port: 443,\n        start_process: true\n      },\n      desiredCapabilities: {\n        'bstack:options': {\n          'userName': 'test-access-user',\n          'accessKey': 'test-access-key'\n        },\n        browserName: 'chrome'\n      },\n      globals: {\n        waitForConditionPollInterval: 10,\n        waitForConditionTimeout: 11,\n        retryAssertionTimeout: 10,\n        reporter(results) {\n          assert.strictEqual(sessionNockCalled, 2);\n          assert.strictEqual(statusSetNockCalled, 1);\n          assert.strictEqual(Object.keys(results.modules).length, 1);\n        }\n      }\n    }));\n  });\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunTestcase.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunTestcase', function() {\n\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  afterEach(function() {\n    Object.keys(require.cache).filter(i => i.includes('/sampletests')).forEach(function(module) {\n      delete require.cache[module];\n    });\n  });\n\n  it('testRunner with skip_testcases_on_fail=false', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withfailures');\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 6);\n        assert.strictEqual(results.passed, 2);\n        assert.strictEqual(results.failed, 2);\n        assert.strictEqual(results.errors, 0);\n\n        cb();\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals,\n      skip_testcases_on_fail: false,\n      output: false\n    }));\n  });\n\n  it('testRunner with skip_testcases_on_fail=true (default)', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withfailures');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 4);\n        assert.strictEqual(results.passed, 1);\n        assert.strictEqual(results.failed, 1);\n        assert.strictEqual(results.errors, 0);\n\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests(testsPath, settings({\n      output: false,\n      globals\n    }));\n  });\n\n  it('testRunner with --testcase argument', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after/syncBeforeAndAfter.js');\n    const globals = {\n      reporter(results, cb) {\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n        assert.ok('demoTestSyncOne' in results.modules.syncBeforeAndAfter.completed);\n\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath],\n      testcase: 'demoTestSyncOne'\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with invalid --testcase argument', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after/syncBeforeAndAfter.js');\n    const globals = {\n      reporter(results, cb) {\n        assert.strictEqual(Object.keys(results.modules).length, 0);\n\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath],\n      testcase: 'Unknown'\n    }, settings({\n      globals\n    }))\n      .then(_ => {\n        assert.ok(false, 'Test runner should have failed with invalid testcase error message');\n      })\n      .catch(err => {\n        assert.strictEqual(err.message, '\"Unknown\" is not a valid testcase in the current test suite.');\n      });\n  });\n\n  it('testRunCurrentTestName', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after/sampleSingleTest.js');\n\n    const globals = {\n      beforeEach(client, cb) {\n        assert.strictEqual(client.currentTest.name, '');\n        assert.strictEqual(client.currentTest.group, '');\n        assert.strictEqual(client.currentTest.module, 'sampleSingleTest');\n        cb();\n      },\n      afterEach(client, cb) {\n        assert.strictEqual(client.currentTest.name, 'demoTest');\n        assert.strictEqual(client.currentTest.module, 'sampleSingleTest');\n        cb();\n      },\n      reporter(results, cb) {\n        assert.ok('sampleSingleTest' in results.modules);\n        assert.ok('demoTest' in results.modules.sampleSingleTest.completed);\n\n        cb();\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('currentTest in afterEach hook', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withaftereach/sampleSingleTest.js');\n    const globals = {\n      reporter(results, cb) {\n        if (results.lastError instanceof Error) {\n          throw results.lastError;\n        }\n        cb();\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with retries', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withfailures');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 6);\n        assert.strictEqual(results.passed, 1);\n        assert.strictEqual(results.failed, 1);\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(results.skipped, 1);\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests({\n      retries: 1,\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with retries and describe', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withdescribe/failures/sampleTest.js');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 6);\n        assert.strictEqual(results.passed, 1);\n        assert.strictEqual(results.failed, 1);\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(results.skipped, 1);\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests({\n      retries: 1,\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with retries and describe with attribute', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withdescribe/failures/sampleTestWithAttribute.js');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 6);\n        assert.strictEqual(results.passed, 1);\n        assert.strictEqual(results.failed, 1);\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(results.skipped, 1);\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with retries and describe with attribute and argument', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withdescribe/failures/sampleTestWithAttribute.js');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 6);\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests({\n      retries: 2,\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with skipped testcases', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withdescribe/skipped/skipTestcase.js');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 2);\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with duplicated testcases', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withdescribe/skipped/duplicateTestcases.js');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 0);\n        assert.strictEqual(results.skipped, 2);\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with skipped beforeEach afterEach hooks', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withdescribe/skipped/skipBeforeAfterEach.js');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 4);\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with disabled testsuite - xdescribe', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withdescribe/skipped/skipTestsuite.js');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 0);\n        assert.strictEqual(Object.keys(results.modules.skipTestsuite.completed).length, 0);\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with retries and skip_testcases_on_fail=false', function() {\n    this.timeout(100000);\n\n    const testsPath = path.join(__dirname, '../../sampletests/withfailures');\n    const globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 10);\n        assert.strictEqual(results.passed, 2);\n        assert.strictEqual(results.failed, 2);\n        assert.strictEqual(results.errors, 0);\n        cb();\n      },\n      retryAssertionTimeout: 0\n    };\n\n    return runTests({\n      retries: 1,\n      _source: [testsPath]\n    }, settings({\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n\n  it('testRunner throwing error with unknown require', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withuknownRequire/sample.js');\n\n    return runTests({\n      retries: 1,\n      _source: [testsPath]\n    }, settings({\n      skip_testcases_on_fail: false\n    })).catch((err) => {\n      assert.strictEqual(err.displayed, true);\n      assert.match(err.message, /Cannot find module 'utilWhichDoesnotexist.js'/);\n    });\n  });\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunTestsuite.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunTestSuite', function () {\n\n  beforeEach(function (done) {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function (done) {\n    CommandGlobals.afterEach.call(this, function () {\n      Object.keys(require.cache).forEach(function (module) {\n        delete require.cache[module];\n      });\n\n      done();\n    });\n  });\n\n  it('testRunner with --fail-fast cli argument', function () {\n    let src_folders = [\n      path.join(__dirname, '../../sampletests/withfailures'),\n      path.join(__dirname, '../../sampletests/withsubfolders')\n    ];\n\n    let globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n        cb();\n      }\n    };\n\n    return runTests({\n      'fail-fast': true\n    }, settings({\n      output: false,\n      src_folders,\n      globals\n    })).catch(err => {\n      return err;\n    }).then(err => {\n      assert.ok(err instanceof Error);\n    });\n  });\n\n  it('testRunner with enable_fail_fast setting', function () {\n    let src_folders = [\n      path.join(__dirname, '../../sampletests/withfailures'),\n      path.join(__dirname, '../../sampletests/withsubfolders')\n    ];\n\n    let globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n        cb();\n      }\n    };\n\n    return runTests({\n    }, settings({\n      output: false,\n      enable_fail_fast: true,\n      src_folders,\n      globals\n    })).catch(err => {\n      return err;\n    }).then(err => {\n      assert.ok(err instanceof Error);\n    });\n  });\n\n  it('testRunModuleSyncName', function () {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      postdata: '{\"using\":\"css selector\",\"value\":\"#finlandia\"}',\n      response: JSON.stringify({sessionId: '1352110219202', status: 0, value: [{ELEMENT: '10'}]})\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      statusCode: 200,\n      method: 'POST',\n      response: JSON.stringify({sessionId: '1352110219202', status: 0, value: true})\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element',\n      statusCode: 200,\n      response: JSON.stringify({sessionId: '1352110219202', status: 0, value: {ELEMENT: '10'}})\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/10/text',\n      statusCode: 200,\n      method: 'GET',\n      response: JSON.stringify({sessionId: '1352110219202', status: 0, value: 'jean sibelius'})\n    }, true);\n\n    let globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.ok('sampleTest' in results.modules);\n        assert.strictEqual(results.errors, 0);\n        if (results.lastError) {\n          throw results.lastError;\n        }\n        cb();\n      },\n      afterEach(client, cb) {\n        assert.strictEqual(client.options.desiredCapabilities.name, 'Sample Test');\n        cb();\n      }\n    };\n\n    let testsPath = path.join(__dirname, '../../sampletests/syncnames');\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      sync_test_names: true,\n      globals\n    }));\n\n  });\n\n  it('test run multiple sources and same module name', function () {\n    let srcFolders = [\n      path.join(__dirname, '../../sampletests/simple'),\n      path.join(__dirname, '../../sampletests/mixed')\n    ];\n\n    let globals = {\n      reporter(results, cb) {\n        assert.ok(`test${path.sep}sample` in results.modules);\n        assert.ok(`mixed${path.sep}sample` in results.modules);\n        assert.ok('demoTest' in results.modules[`test${path.sep}sample`].completed);\n        assert.ok('demoTestMixed' in results.modules[`mixed${path.sep}sample`].completed);\n\n        cb();\n      }\n    };\n\n    return runTests(settings({\n      globals,\n      start_session: true,\n      src_folders: srcFolders\n    }));\n  });\n\n  it('testRunMultipleSrcFolders', function () {\n    let srcFolders = [\n      path.join(__dirname, '../../sampletests/simple'),\n      path.join(__dirname, '../../sampletests/srcfolders')\n    ];\n\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          if (results.lastError) {\n            throw results.lastError;\n          }\n          assert.ok(`test${path.sep}sample` in results.modules);\n          assert.ok('demoTest' in results.modules[`test${path.sep}sample`].completed);\n          assert.ok(`srcfolders${path.sep}other_sample` in results.modules);\n\n          const stringPath = ['test', 'sampletests', 'simple', 'test', 'sample.js'].join(path.sep);\n          assert.strictEqual(results.modules[`test${path.sep}sample`].modulePath.endsWith(stringPath), true);\n          cb();\n        }\n      },\n      src_folders: srcFolders\n    }));\n  });\n\n  it('test runner with multiple test interfaces - exports/describe', function () {\n    let srcFolders = [\n      path.join(__dirname, '../../sampletests/simple'),\n      path.join(__dirname, '../../sampletests/withdescribe/basic')\n    ];\n\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          if (results.lastError) {\n            throw results.lastError;\n          }\n          assert.ok(`test${path.sep}sample` in results.modules);\n          assert.ok('demoTest' in results.modules[`test${path.sep}sample`].completed);\n          let test = results.modules[`test${path.sep}sample`].completed.demoTest;\n          assert.strictEqual(test.assertions.length, 2);\n          assert.strictEqual(test.passed, 2);\n\n          assert.ok(`basic${path.sep}sample` in results.modules);\n          test = results.modules[`basic${path.sep}sample`].completed.demoTest;\n          assert.strictEqual(test.assertions.length, 2);\n          assert.strictEqual(test.passed, 2);\n          cb();\n        }\n      },\n      src_folders: srcFolders\n    }));\n  });\n\n  it('test runner with describe and .only()', function () {\n    let srcFolders = [\n      path.join(__dirname, '../../sampletests/withdescribe/basic/sampleWithOnly.js')\n    ];\n\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          if (results.lastError) {\n            throw results.lastError;\n          }\n\n          const testcases = results.modules.sampleWithOnly.completed;\n          assert.deepStrictEqual(Object.keys(testcases), ['demoTest two']);\n          cb();\n        }\n      },\n      src_folders: srcFolders\n    }));\n  });\n\n  it('testRunner with describe and skipTestcasesOnFail=true', function () {\n    let testsPath = path.join(__dirname, '../../sampletests/withdescribe/failures/sampleSkipTestcases.js');\n    let globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 2);\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(results.failed, 2);\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      globals,\n      output: false,\n      skip_testcases_on_fail: true\n    }));\n  });\n\n  it('testRunner with parallel mode and single test source', function () {\n    let testsPath = path.join(__dirname, '../../sampletests/withdescribe/failures/sampleSkipTestcases.js');\n    let globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(this.settings.testWorkersEnabled, false);\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      globals,\n      output: false,\n      test_workers: true\n    }));\n  });\n\n  it('test worker mode and single test source', function () {\n    let testsPath = path.join(__dirname, '../../sampletests/withdescribe/failures/sampleSkipTestcases.js');\n    let globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(this.settings.testWorkersEnabled, true);\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath],\n      'test-worker': true\n    }, settings({\n      globals,\n      output: false,\n      test_workers: true\n    }));\n  });\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunTestsuiteWithSuiteRetries.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests, CliRunner} = common.require('index.js');\n\ndescribe('testRunTestsuiteWithSuiteRetries', function() {\n\n  beforeEach(function(done) {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, function() {\n      Object.keys(require.cache).forEach(function(module) {\n        delete require.cache[module];\n      });\n\n      done();\n    });\n  });\n\n  it('testRunner with suiteRetries', function() {\n    let sessionFinishedCalled = false;\n    let testsPath = path.join(__dirname, '../../sampletests/withfailures');\n    let globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(sessionFinishedCalled, true, 'sessionFinished was not called');\n        assert.strictEqual(globals.calls, 8);\n        assert.deepStrictEqual(results.errmessages, []);\n        assert.strictEqual(results.passed, 1);\n        assert.strictEqual(results.failed, 1);\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(results.skipped, 1);\n        cb();\n      }\n    };\n\n\n    const Transport = common.require('transport/selenium-webdriver/selenium.js');\n    Transport.prototype.sessionFinished = function() {\n      sessionFinishedCalled = true;\n    };\n\n    const runner = CliRunner({\n      suiteRetries: 1,\n      _source: [testsPath]\n    });\n\n    runner.setup(settings({\n      globals\n    }));\n\n    return runner.runTests();\n  });\n\n  it('testRunner with suiteRetries and describe interface', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withdescribe/suite-retries/sample.js');\n\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 8);\n        assert.deepStrictEqual(results.errmessages, []);\n        assert.strictEqual(results.passed, 1);\n        assert.strictEqual(results.failed, 1);\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(results.skipped, 1);\n        cb();\n      }\n    };\n\n    return runTests({\n      suiteRetries: 1,\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with suiteRetries and describe interface with attribute', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withdescribe/suite-retries/sampleWithAttribute.js');\n\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 8);\n        assert.deepStrictEqual(results.errmessages, []);\n        assert.strictEqual(results.passed, 1);\n        assert.strictEqual(results.failed, 1);\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(results.skipped, 1);\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with suiteRetries and describe interface with both attribute and argument', function() {\n    const testsPath = path.join(__dirname,\n      '../../sampletests/withdescribe/suite-retries/sampleWithAttribute.js');\n\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 8);\n        cb();\n      }\n    };\n\n    return runTests({\n      suiteRetries: 2,\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with suiteRetries and skip_testcases_on_fail=false', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/withfailures');\n    let globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 12);\n        assert.strictEqual(results.errors, 0);\n        cb();\n      }\n    };\n\n    return runTests({\n      suiteRetries: 1,\n      _source: [testsPath]\n    }, settings({\n      globals,\n      skip_testcases_on_fail: false\n    }));\n  });\n\n  it('testRunner with suiteRetries and enable_fail_fast=true', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/withfailures');\n    let globals = {\n      calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 12);\n        cb();\n      }\n    };\n\n    return runTests({}, settings({\n      suiteRetries: 2,\n      _source: [testsPath],\n      enable_fail_fast: true,\n      globals\n    })).catch(err => {\n      return err;\n    }).then(err => {\n      assert.ok(err instanceof Error);\n    });\n  });\n\n  it('testRunner with suiteRetries and locate strategy change', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/suiteretries/locate-strategy');\n    let globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(runner.currentSuite.client.locateStrategy, 'css selector');\n        cb();\n      }\n    };\n\n    const Runner = common.require('runner/runner.js');\n    const Settings = common.require('settings/settings.js');\n\n    const settings = Settings.parse({\n      selenium: {\n        port: 10195,\n        start_process: false\n      },\n      selenium_host: 'localhost',\n      silent: false,\n      output: false,\n      persist_globals: true,\n      globals,\n      skip_testcases_on_fail: false,\n      output_folder: false\n    });\n\n    const argv = {\n      reporter: 'junit',\n      suiteRetries: 1,\n      _source: [testsPath]\n    };\n\n    let runner = Runner.create(settings, argv);\n\n    return Runner.readTestSource(settings, argv)\n      .then(modules => {\n        return runner.run(modules);\n      });\n  });\n\n  it('test clear command queue when run with suiteRetries', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/suiteretries/sample');\n    let globals = {\n      calls: 0,\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 3);\n        assert.strictEqual(results.passed, 2);\n        cb();\n      }\n    };\n\n    return runTests({\n      suiteRetries: 1,\n      _source: [testsPath]\n    }, settings({\n      globals\n    }));\n  });\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunWithCommandErrors.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunWithCommandErrors', function() {\n\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  describe('testRunWithWindowCommandErrors', function() {\n    it('testRunner with socket hang up error and retry then success', function() {\n      let requestCount = 0;\n\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/frame/parent',\n        socketDelay: 200,\n        response: '',\n        times: 2,\n        onRequest() {\n          requestCount++;\n        }\n      });\n\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/frame/parent',\n        statusCode: 200,\n        response: {\n          value: null\n        },\n        onRequest() {\n          requestCount++;\n        }\n      }, true);\n\n      const testsPath = path.join(__dirname, '../../sampletests/withcommanderrors');\n      const globals = {\n        retryAssertionTimeout: 90,\n        abortOnElementLocateError: true,\n        waitForConditionTimeout: 90,\n        waitForConditionPollInterval: 90,\n        reporter(results, cb) {\n          assert.strictEqual(results.errmessages.length, 0);\n          assert.strictEqual(requestCount, 3);\n          assert.strictEqual(results.passed, 1);\n          assert.strictEqual(results.failed, 0);\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errors, 0);\n          assert.strictEqual(results.skipped, 0);\n          cb();\n        }\n      };\n\n      return runTests({\n        _source: [testsPath]\n      }, settings({\n        webdriver: {\n          timeout_options: {\n            timeout: 50,\n            retry_attempts: 2\n          }\n        },\n        output: false,\n        report_command_errors: true,\n        skip_testcases_on_fail: false,\n        disable_error_log: 0,\n        globals\n      }));\n    });\n    \n    it('testRunner with error and report errors on', function() {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/frame/parent',\n        statusCode: 500,\n        response: {\n          sessionId: null,\n          state: 'unhandled error',\n          value: {\n            message: 'POST /session'\n          },\n          status: 13\n        }\n      }, true);\n\n      const testsPath = path.join(__dirname, '../../sampletests/withcommanderrors');\n      const globals = {\n        retryAssertionTimeout: 90,\n        abortOnElementLocateError: true,\n        waitForConditionTimeout: 90,\n        waitForConditionPollInterval: 90,\n        reporter(results, cb) {\n          assert.strictEqual(results.errmessages.length, 1);\n          assert.ok(results.errmessages[0].includes('Error while running .frameParent():'));\n          assert.strictEqual(results.passed, 1);\n          assert.strictEqual(results.failed, 0);\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errors, 1);\n          assert.strictEqual(results.skipped, 0);\n          cb();\n        }\n      };\n\n      return runTests({\n        _source: [testsPath]\n      }, settings({\n        output: false,\n        report_command_errors: true,\n        skip_testcases_on_fail: false,\n        disable_error_log: 0,\n        webdriver: {\n          timeout_options: {\n            retry_attempts: 0\n          }\n        },\n        globals\n      }));\n    });\n\n    it('testRunner with socket hang up error', function() {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/frame/parent',\n        socketDelay: 200,\n        response: ''\n      }, null, true);\n\n      const testsPath = path.join(__dirname, '../../sampletests/withcommanderrors');\n      const globals = {\n        retryAssertionTimeout: 90,\n        abortOnElementLocateError: true,\n        waitForConditionTimeout: 90,\n        waitForConditionPollInterval: 90,\n        reporter(results, cb) {\n          assert.strictEqual(results.errmessages.length, 1);\n          assert.ok(results.errmessages[0].includes('Error while running .frameParent(): Error: ECONNRESET socket hang up'));\n          assert.strictEqual(results.passed, 1);\n          assert.strictEqual(results.failed, 0);\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errors, 1);\n          assert.strictEqual(results.skipped, 0);\n          cb();\n        }\n      };\n\n      return runTests({\n        _source: [testsPath]\n      }, settings({\n        webdriver: {\n          timeout_options: {\n            timeout: 50\n          }\n        },\n        output: false,\n        report_command_errors: true,\n        report_network_errors: true,\n        skip_testcases_on_fail: false,\n        disable_error_log: 0,\n        globals\n      }));\n    });\n\n    it('testRunner with socket hang up error and report_network_errors on', function() {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/frame/parent',\n        socketDelay: 200,\n        response: ''\n      }, null, true);\n\n      const testsPath = path.join(__dirname, '../../sampletests/withcommanderrors');\n      const globals = {\n        retryAssertionTimeout: 90,\n        abortOnElementLocateError: true,\n        waitForConditionTimeout: 90,\n        waitForConditionPollInterval: 90,\n        reporter(results, cb) {\n          assert.strictEqual(results.errmessages.length, 1);\n          assert.ok(results.errmessages[0].includes('Error while running .frameParent(): Error: ECONNRESET socket hang up'));\n          assert.strictEqual(results.passed, 1);\n          assert.strictEqual(results.failed, 0);\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errors, 1);\n          assert.strictEqual(results.skipped, 0);\n          cb();\n        }\n      };\n\n      return runTests({\n        _source: [testsPath]\n      }, settings({\n        webdriver: {\n          timeout_options: {\n            timeout: 50\n          }\n        },\n        output: false,\n        report_network_errors: true,\n        skip_testcases_on_fail: false,\n        disable_error_log: 0,\n        globals\n      }));\n    });\n\n    it('testRunner with socket hang up error and report errors disabled', function() {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/frame/parent',\n        socketDelay: 200,\n        response: ''\n      }, true);\n\n      const testsPath = path.join(__dirname, '../../sampletests/withcommanderrors');\n      const globals = {\n        retryAssertionTimeout: 90,\n        abortOnElementLocateError: true,\n        waitForConditionTimeout: 90,\n        waitForConditionPollInterval: 90,\n        reporter(results, cb) {\n          assert.strictEqual(results.errmessages.length, 0);\n          assert.strictEqual(results.passed, 1);\n          assert.strictEqual(results.failed, 0);\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errors, 0);\n          assert.strictEqual(results.skipped, 0);\n          cb();\n        }\n      };\n\n      return runTests({\n        _source: [testsPath]\n      }, settings({\n        webdriver: {\n          timeout_options: {\n            timeout: 50,\n            retry_attempts: 0\n          }\n        },\n        output: false,\n        report_command_errors: false,\n        report_network_errors: false,\n        skip_testcases_on_fail: false,\n        disable_error_log: 0,\n        globals\n      }));\n    });\n\n\n\n    it('testRunner with open new window socket hang up error and retry then success - default settings', function() {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/frame/parent',\n        socketDelay: 200,\n        response: ''\n      }, true);\n\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/frame/parent',\n        socketDelay: 200,\n        response: ''\n      }, true);\n\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/frame/parent',\n        statusCode: 200,\n        response: {\n          value: null\n        }\n      }, true);\n\n      const testsPath = path.join(__dirname, '../../sampletests/withcommanderrors');\n      const globals = {\n        retryAssertionTimeout: 90,\n        abortOnElementLocateError: true,\n        waitForConditionTimeout: 90,\n        waitForConditionPollInterval: 90,\n        reporter(results, cb) {\n          assert.strictEqual(results.errmessages.length, 0);\n          assert.strictEqual(results.passed, 1);\n          assert.strictEqual(results.failed, 0);\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errors, 0);\n          assert.strictEqual(results.skipped, 0);\n          cb();\n        }\n      };\n\n      return runTests({\n        _source: [testsPath]\n      }, settings({\n        webdriver: {\n          timeout_options: {\n            timeout: 50,\n            retry_attempts: 2\n          }\n        },\n        report_command_errors: false,\n        report_network_errors: false,\n        globals\n      }));\n    });\n\n  });\n\n  describe('testRunWithElementLocateErrors', function() {\n\n    it('testRunner with element locate errors enabled', function() {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#element-error'\n        },\n        statusCode: 200,\n        response: {value: []}\n      }, false, true);\n\n      const testsPath = path.join(__dirname, '../../sampletests/withelementerrors');\n      const globals = {\n        retryAssertionTimeout: 90,\n        abortOnElementLocateError: true,\n        waitForConditionTimeout: 90,\n        waitForConditionPollInterval: 90,\n        reporter(results, cb) {\n          assert.strictEqual(results.errmessages.length, 1);\n          assert.strictEqual(results.passed, 0);\n          assert.strictEqual(results.failed, 0);\n          assert.strictEqual(results.assertions, 0);\n          assert.strictEqual(results.errors, 1);\n          assert.strictEqual(results.skipped, 0);\n          cb();\n        }\n      };\n\n      return runTests({\n        _source: [testsPath]\n      }, settings({\n        output: false,\n        skip_testcases_on_fail: false,\n        disable_error_log: 0,\n        globals\n      }));\n    });\n\n    it('testRunner with element locate errors disabled', function() {\n      MockServer.addMock({\n        url: '/wd/hub/session/1352110219202/elements',\n        postdata: {\n          using: 'css selector',\n          value: '#element-error'\n        },\n        statusCode: 200,\n        response: {value: []}\n      }, false, true);\n\n      const testsPath = path.join(__dirname, '../../sampletests/withelementerrors');\n      const globals = {\n        retryAssertionTimeout: 90,\n        abortOnElementLocateError: false,\n        waitForConditionTimeout: 90,\n        waitForConditionPollInterval: 90,\n        reporter(results, cb) {\n          assert.strictEqual(results.errmessages.length, 1);\n          assert.strictEqual(results.passed, 1);\n          assert.strictEqual(results.failed, 0);\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errors, 1);\n          assert.strictEqual(results.skipped, 0);\n          cb();\n        }\n      };\n\n      return runTests({\n        _source: [testsPath]\n      }, settings({\n        globals\n      }));\n    });\n\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunWithCustomCommands.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst Nightwatch = require('../../lib/nightwatch.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunWithCustomCommands', function() {\n\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  afterEach(function() {\n    Object.keys(require.cache).filter(i => i.includes('/sampletests')).forEach(function(module) {\n      delete require.cache[module];\n    });\n  });\n\n  it('testRunner with custom command which has failures', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withcustomcommands');\n    const globals = {\n      increment: 0,\n      retryAssertionTimeout: 0,\n      waitForConditionPollInterval: 10,\n      waitForConditionTimeout: 20,\n      reporter(results, cb) {\n        assert.strictEqual(globals.increment, 6);\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      custom_commands_path: [path.join(__dirname, '../../extra/commands')],\n      globals\n    }));\n  });\n\n  it('testRunner with ES6 Async custom commands', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withes6asynccommands');\n    let testResults;\n    const origExit = process.exit;\n    process.exit = function() {};\n\n    const globals = {\n      increment: 0,\n      logResult: null,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        testResults = results;\n\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      custom_commands_path: [path.join(__dirname, '../../extra/commands/es6async')],\n      output: false,\n      globals\n    })).then(_ => {\n      process.exit = origExit;\n      assert.strictEqual(globals.increment, 3);\n      assert.deepStrictEqual(globals.logResult, [\n        {\n          level: {value: 0, name: 'ALL'},\n          type: '',\n          timestamp: 534547832,\n          message: 'Test log'\n        },\n        {\n          level: {value: 0, name: 'ALL'},\n          type: '',\n          timestamp: 534547442,\n          message: 'Test log2'\n        }\n      ]);\n      assert.strictEqual(testResults.errors, 0);\n      assert.strictEqual(testResults.lastError, undefined);\n      assert.strictEqual(testResults.errmessages.length, 0);\n    });\n  });\n\n  it('testRunner with ES6 Async custom commands', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withes6asynccommands');\n    let testResults;\n    const origExit = process.exit;\n    process.exit = function() {};\n\n    const globals = {\n      increment: 0,\n      logResult: null,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        testResults = results;\n\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      custom_commands_path: [path.join(__dirname, '../../extra/commands/es6async')],\n      output: false,\n      globals\n    })).then(_ => {\n      process.exit = origExit;\n      assert.strictEqual(globals.increment, 3);\n      assert.deepStrictEqual(globals.logResult, [\n        {\n          level: {value: 0, name: 'ALL'},\n          type: '',\n          timestamp: 534547832,\n          message: 'Test log'\n        },\n        {\n          level: {value: 0, name: 'ALL'},\n          type: '',\n          timestamp: 534547442,\n          message: 'Test log2'\n        }\n      ]);\n      assert.strictEqual(testResults.errors, 0);\n      assert.strictEqual(testResults.lastError, undefined);\n      assert.strictEqual(testResults.errmessages.length, 0);\n    });\n  });\n\n  it('testRunner custom command which extends built-in command', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withcustomcommands/element');\n    let testResults;\n    const origExit = process.exit;\n    process.exit = function() {};\n\n    const globals = {\n      increment: 0,\n      logResult: null,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        if (results.lastError instanceof Error) {\n          throw results.lastError;\n        }\n        testResults = results;\n\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      custom_commands_path: [path.join(__dirname, '../../extra/commands')],\n      globals\n    })).then(_ => {\n      process.exit = origExit;\n\n\n      assert.strictEqual(testResults.errmessages.length, 0);\n      assert.strictEqual(testResults.assertions, 1);\n      assert.strictEqual(testResults.passed, 1);\n    });\n  });\n\n  it('test custom command - custom execute async', async function () {\n    MockServer.addMock({\n      url: '/session/13521-10219-202/execute/sync',\n      method: 'POST'\n    });\n\n    await Nightwatch.initAsync({\n      output: false,\n      silent: false,\n      selenium: {\n        start_process: false,\n        host: null\n      },\n      custom_commands_path: [path.join(__dirname, '../../extra/commands/es6async')]\n    });\n\n    return new Promise((resolve, reject) => {\n      Nightwatch.api().customExecuteAsync({prop: true}, function(endTime) {\n        let finished = false;\n        const {tree} = Nightwatch.client().queue;\n        const root = tree.__rootNode__;\n        tree.on('asynctree:finished', function() {\n          finished = true;\n        });\n\n        try {\n          assert.strictEqual(root.childNodes[0].name, 'customExecuteAsync');\n          assert.strictEqual(root.childNodes[0].done, false);\n          assert.ok(endTime > 100, `error with async callback; endTime = ${endTime}`);\n        } catch (err) {\n          reject(err);\n\n          return;\n        }\n\n        setTimeout(function() {\n          try {\n            assert.strictEqual(finished, true);\n            resolve();\n          } catch (err) {\n            reject(err);\n          }\n        }, 50);\n      });\n    });\n  });\n\n  it('testRunner custom command path as glob pattern', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withcustomcommands/element');\n    let testResults;\n    const origExit = process.exit;\n    process.exit = function() {};\n\n    const globals = {\n      increment: 0,\n      logResult: null,\n      retryAssertionTimeout: 0,\n      reporter(results, cb) {\n        if (results.lastError instanceof Error) {\n          throw results.lastError;\n        }\n        testResults = results;\n\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      custom_commands_path: [path.join(__dirname, '../../extra/commands/*.js')],\n      globals\n    })).then(_ => {\n      process.exit = origExit;\n\n      assert.strictEqual(testResults.errmessages.length, 0);\n      assert.strictEqual(testResults.assertions, 1);\n      assert.strictEqual(testResults.passed, 1);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunWithExclude.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\nconst originalCwd = process.cwd();\n\ndescribe('testRunWithExclude', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  beforeEach(function(done) {\n    process.chdir(path.join(__dirname, '../../sampletests/'));\n    done();\n  });\n\n  afterEach(function(done) {\n    process.chdir(originalCwd);\n    done();\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('testRunWithExcludeFolder', function() {\n    return runTests({\n      _source: ['./withexclude']\n    }, settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(!(`excluded${path.sep}excluded-module` in results.modules));\n          assert.ok(!(`excluded${path.sep}not-excluded` in results.modules));\n          assert.ok(`simple${path.sep}sample` in results.modules);\n\n          cb();\n        }\n      },\n      exclude: ['./withexclude/excluded']\n    }));\n  });\n\n  it('testRun with exclude folder name and multiple src_folders', function()  {\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(`excluded${path.sep}excluded-module` in results.modules);\n          assert.ok(`excluded${path.sep}not-excluded` in results.modules);\n          assert.ok(!(`simple${path.sep}sample` in results.modules));\n\n          cb();\n        }\n      },\n      src_folders: ['./withexclude/excluded', './withexclude/simple'],\n      exclude: './withexclude/simple'\n    }));\n  });\n\n  it('testRun with exclude folder pattern and multiple src_folders', function()  {\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(`excluded${path.sep}excluded-module` in results.modules);\n          assert.ok(`excluded${path.sep}not-excluded` in results.modules);\n          assert.ok(!(`simple${path.sep}sample` in results.modules));\n\n          cb();\n        }\n      },\n      src_folders: ['./withexclude/excluded', './withexclude/simple'],\n      exclude: './withexclude/simple/*'\n    }));\n  });\n\n  it('testRun with filter folder name and multiple src_folders', function()  {\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(!(`excluded${path.sep}excluded-module` in results.modules));\n          assert.ok(!(`excluded${path.sep}not-excluded` in results.modules));\n          assert.ok(`simple${path.sep}sample` in results.modules);\n\n          cb();\n        }\n      },\n      src_folders: ['./withexclude/excluded', './withexclude/simple'],\n      filter: 'withexclude/simple'\n    }));\n  });\n\n  it('testRun with filter pattern and multiple src_folders', function()  {\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(!(`excluded${path.sep}excluded-module` in results.modules));\n          assert.ok(!(`excluded${path.sep}not-excluded` in results.modules));\n          assert.ok(`simple${path.sep}sample` in results.modules);\n\n          cb();\n        }\n      },\n      src_folders: ['./withexclude/excluded', './withexclude/simple'],\n      filter: 'withexclude/simple/*'\n    }));\n  });\n\n  it('testRun with filter pattern relative and single src_folders', function()  {\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(!(`excluded${path.sep}excluded-module` in results.modules));\n          assert.ok(!(`excluded${path.sep}not-excluded` in results.modules));\n          assert.ok(`simple${path.sep}sample` in results.modules);\n\n          cb();\n        }\n      },\n      src_folders: ['./withexclude'],\n      filter: 'simple/*'\n    }));\n  });\n\n  it('testRun with both filter and exclude patterns and single src_folder', function()  {\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(!(`excluded${path.sep}excluded-module` in results.modules));\n          assert.ok(`excluded${path.sep}not-excluded` in results.modules);\n          assert.ok(!(`simple${path.sep}sample` in results.modules));\n\n          cb();\n        }\n      },\n      src_folders: ['./withexclude'],\n      filter: 'excluded/*',\n      exclude: 'excluded/excluded-*'\n    }));\n  });\n\n  it('testRunWithExcludePattern', function()  {\n    return runTests({\n      _source: ['./withexclude']\n    }, settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(!(`excluded${path.sep}excluded-module` in results.modules));\n          assert.ok(`excluded${path.sep}not-excluded` in results.modules);\n          assert.ok(`simple${path.sep}sample` in results.modules);\n\n          cb();\n        }\n      },\n      exclude: ['withexclude/excluded/excluded-*'],\n      start_session: true\n    }));\n  });\n\n  it('testRunWithExcludeFile', function()  {\n    return runTests({\n      _source: [path.join(__dirname, '../../sampletests/withexclude')]\n    }, settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(!(`excluded${path.sep}excluded-module` in results.modules));\n          assert.ok(`excluded${path.sep}not-excluded` in results.modules);\n          assert.ok(`simple${path.sep}sample` in results.modules);\n          cb();\n        }\n      },\n      exclude: [path.join('withexclude', 'excluded', 'excluded-module.js')],\n      start_session: true\n    }));\n  });\n\n  it('test running with multiple excludes will exclude all matches with single src folder', function()  {\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(!(`excluded${path.sep}excluded-module` in results.modules));\n          assert.ok(`excluded${path.sep}not-excluded` in results.modules);\n          assert.ok(!(`simple${path.sep}sample` in results.modules));\n\n          cb();\n        }\n      },\n      src_folders: './withexclude',\n      exclude: [\n        path.join('withexclude', 'excluded', 'excluded-module.js'),\n        path.join('withexclude', 'simple')\n      ]\n    }));\n  });\n\n  it('test running with multiple excludes will exclude all matches with multiple src folders', function()  {\n    return runTests(settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok(!(`excluded${path.sep}excluded-module` in results.modules));\n          assert.ok(`excluded${path.sep}not-excluded` in results.modules);\n          assert.ok(!(`simple${path.sep}sample` in results.modules));\n\n          cb();\n        }\n      },\n      src_folders: [\n        path.join('withexclude', 'excluded'),\n        path.join('withexclude', 'simple')\n      ],\n      exclude: [\n        path.join('withexclude', 'excluded', 'excluded-module.js'),\n        path.join('withexclude', 'simple')\n      ]\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunWithExistingCommands.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunWithExistingCommands', function () {\n\n  it('testRunner with element locate errors enabled', function () {\n    let testsPath = path.join(__dirname, '../../sampletests/');\n\n    let globals = {\n      retryAssertionTimeout: 90,\n      abortOnElementLocateError: true,\n      waitForConditionTimeout: 90,\n      waitForConditionPollInterval: 90,\n      reporter(results, cb) {\n\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      output: true,\n      custom_commands_path: [path.join(__dirname, '../../extra/existing-custom-commands')],\n      globals\n    })).catch(err => {\n      assert.strictEqual(err.message, 'Error while loading the API commands: the command .click() is already defined.');\n      assert.strictEqual(err.name, 'TypeError');\n    })\n\n  });\n\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunWithExternalGlobals.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunWithExternalGlobals', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('testRun with external globals', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/before-after/sampleSingleTest.js');\n    const globals = {\n      reporterCount: 0\n    };\n\n    return runTests(testsPath, settings({\n      globals,\n      globals_path: path.join(__dirname, '../../extra/external-globals.js'),\n\n      output_folder: false\n    }));\n  });\n\n  it('testRun with async external globals', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/before-after/sampleSingleTest.js');\n    const globals = {\n      reporterCount: 0\n    };\n\n    return runTests(testsPath, settings({\n      globals,\n      globals_path: path.join(__dirname, '../../extra/external-globals-async.js'),\n      output_folder: false\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunWithGlobalHooks.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\nconst mockery  = require('mockery');\n\ndescribe('testRunWithGlobalHooks', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnUnregistered: false});\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  afterEach(function() {\n    process.env.__NIGHTWATCH_PARALLEL_MODE = null;\n    mockery.deregisterAll();\n    mockery.resetCache();\n    mockery.disable();\n    Object.keys(require.cache).filter(i => i.includes('/sampletests')).forEach(function(module) {\n      delete require.cache[module];\n    });\n  });\n\n  it('testRunner with globalBefore and after', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    let beforeEachCount = 0;\n    let afterEachCount = 0;\n\n    const globals = {\n      calls: 0,\n\n      beforeEach() {\n        beforeEachCount++;\n      },\n      afterEach() {\n        afterEachCount++;\n      },\n      reporter(results, cb) {\n\n        assert.strictEqual(globals.singleTestCalled, true);\n        assert.deepStrictEqual(globals.settings.selenium, {\n          check_process_delay: 500,\n          cli_args: {},\n          log_path: './logs',\n          max_status_poll_tries: 15,\n          port: 10195,\n          server_path: null,\n          start_process: false,\n          status_poll_interval: 200,\n          url: 'http://localhost:10195'\n        });\n        assert.strictEqual(beforeEachCount, 4);\n        assert.strictEqual(afterEachCount, 4);\n        assert.strictEqual(globals.calls, 19);\n        cb();\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  this.timeout(10000);\n\n  it('testRunner with global async beforeEach and afterEach', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    const globals = {\n      calls: 0,\n      beforeEach(cb) {\n        setTimeout(function() {\n          beforeEachCount++;\n          cb();\n        }, 10);\n      },\n      afterEach(cb) {\n        setTimeout(function() {\n          afterEachCount++;\n          cb();\n        }, 15);\n      },\n      reporter(results, cb) {\n        assert.strictEqual(beforeEachCount, 4);\n        assert.strictEqual(afterEachCount, 4);\n        assert.strictEqual(globals.calls, 19);\n        cb();\n      }\n    };\n    let beforeEachCount = 0;\n    let afterEachCount = 0;\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with global async beforeEach and afterEach with api argument', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    const globals = {\n      calls: 0,\n      beforeEach(client, done) {\n        assert.deepStrictEqual(client.globals, this);\n        setTimeout(function() {\n          beforeEachCount++;\n          done();\n        }, 10);\n      },\n      afterEach(client, cb) {\n        setTimeout(function() {\n          afterEachCount++;\n          cb();\n        }, 10);\n      },\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 19);\n        assert.strictEqual(beforeEachCount, 4);\n        assert.strictEqual(afterEachCount, 4);\n        cb();\n      }\n    };\n\n    let beforeEachCount = 0;\n    let afterEachCount = 0;\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('test run with global async beforeEach and assert failure', function() {\n    let beforeEachCount = 0;\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n\n    return runTests(testsPath, settings({\n      globals: {\n        beforeEach: function(client, done) {\n          client.perform(function() {\n            beforeEachCount++;\n            client.assert.strictEqual(0, 1);\n            done();\n          });\n        },\n        reporter(results, cb) {\n          assert.ok(results.lastError instanceof Error);\n          assert.strictEqual(results.failed, 4);\n          assert.strictEqual(beforeEachCount, 4);\n          cb();\n        }\n      }\n    }));\n  });\n\n  it('test run with global async beforeEach and exception', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after/');\n\n    return runTests(testsPath, settings({\n      output: false,\n      globals: {\n        asyncHookTimeout: 200,\n        beforeEach(client, done) {\n          client\n            .perform(function() {\n              throw new Error('From global beforeEach');\n            });\n        },\n        reporter(results, cb) {\n          assert.deepStrictEqual(Object.keys(results.modules), [\n            'sampleSingleTest',\n            'sampleWithBeforeAndAfter',\n            'sampleWithBeforeAndAfterNoCallback',\n            'syncBeforeAndAfter'\n          ]);\n          assert.strictEqual(results.modules.sampleSingleTest.errmessages.length, 2);\n          assert.strictEqual(results.modules.sampleWithBeforeAndAfter.errmessages.length, 1);\n          assert.strictEqual(results.modules.syncBeforeAndAfter.errmessages.length, 1);\n          assert.ok(results.modules.sampleSingleTest.errmessages[0].includes('Error while running \"perform\" command:'));\n\n          cb();\n        }\n      }\n    }));\n  });\n\n  it('test run with global async beforeEach and timeout error', async function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n\n    let expectedErr;\n\n    try {\n      await runTests(testsPath, settings({\n        globals: {\n          asyncHookTimeout: 100,\n          before(done) {\n          }\n        }\n      }));\n    } catch (err) {\n      expectedErr = err;\n    }\n\n    assert.ok(expectedErr instanceof Error);\n    assert.ok(expectedErr.message.includes('while executing \"global before\".'));\n  });\n\n  it('test run with global async beforeEach and done(err);', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n\n    return runTests(testsPath, settings({\n      globals: {\n        beforeEach: function(client, cb) {\n          setTimeout(function() {\n            cb(new Error('global beforeEach error'));\n          }, 10);\n        },\n        reporter(results, cb) {\n          assert.ok(results.lastError instanceof Error);\n          assert.strictEqual(results.lastError.message, 'global beforeEach error');\n          cb();\n        }\n      }\n    }));\n  });\n\n  it('test currentTest in global beforeEach/afterEach', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withfailures');\n    const globals = {\n      calls: 0,\n      waitForConditionPollInterval: 5,\n      waitForConditionTimeout: 5,\n      retryAssertionTimeout: 10,\n      beforeEach: function(client, done) {\n        const testTimestamp = new Date(client.currentTest.timestamp);\n        const currentTimestamp = new Date();\n\n        assert.ok(testTimestamp);\n        assert.strictEqual(testTimestamp.getFullYear(), currentTimestamp.getFullYear());\n        assert.strictEqual(testTimestamp.getMonth(), currentTimestamp.getMonth());\n        assert.strictEqual(testTimestamp.getDate(), currentTimestamp.getDate());\n        assert.deepStrictEqual(client.currentTest.results, {errors: 0, failed: 0, passed: 0, assertions: [], commands: [], tests: 0});\n        assert.strictEqual(client.currentTest.module, 'sample');\n        assert.strictEqual(client.currentTest.name, '');\n        globals.calls++;\n        done();\n      },\n\n      afterEach: function(client, done) {\n        assert.deepStrictEqual(client.currentTest.results.steps, ['demoTest2']);\n        assert.strictEqual(client.currentTest.results.passed, 1);\n        assert.strictEqual(client.currentTest.results.failed, 1);\n        assert.strictEqual(client.currentTest.results.tests, 2);\n        assert.ok('demoTest' in client.currentTest.results.testcases);\n\n        assert.deepStrictEqual(client.currentTest.name, 'demoTest');\n        assert.deepStrictEqual(client.currentTest.module, 'sample');\n        assert.ok(client.currentTest.timestamp);\n        globals.calls++;\n        done();\n      },\n\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 6);\n\n        cb();\n      }\n    };\n\n    return runTests(testsPath, settings({\n      output: false,\n      globals\n    }));\n  });\n\n  it('test global child process hooks - child process',  function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    process.env.__NIGHTWATCH_PARALLEL_MODE = '1';\n    const globals = {\n      calls: 0,\n      beforeChildProcess() {\n        globals.calls++;\n      },\n      afterChildProcess() {\n        globals.calls++;\n      },\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 20);\n        cb();\n      }\n    };\n\n    return runTests(testsPath, settings({\n      output: false,\n      use_child_process: true,\n      globals\n    })\n    );\n  });\n\n  it('test global child process hooks - worker threads',  function() {\n    mockery.registerMock('./worker-process.js', class WorkerProcess {\n      static get isWorkerThread() {\n        return true;\n      }\n    });\n    \n    const processPort = process.port;\n    process.port = {\n      postMessage: function(){}\n    };\n\n    const  testsPath = path.join(__dirname, '../../sampletests/before-after');\n    \n    const globals = {\n      calls: 0,\n      beforeChildProcess() {\n        globals.calls++;\n      },\n      afterChildProcess() {\n        globals.calls++;\n      },\n      reporter(results, cb) {\n        assert.strictEqual(globals.calls, 20);\n        process.port = processPort;\n        cb();\n      }\n    };\n\n    return runTests(testsPath, settings({\n      use_child_process: false,\n      output: false,\n      globals\n    })\n    );\n  });\n\n\n  it('test global async child process hooks - child process',  function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    process.env.__NIGHTWATCH_PARALLEL_MODE = '1';\n    const globals = {\n      calls: 0,\n      beforeChildProcess(_, done) {\n        setTimeout(function() {\n          globals.calls++;\n          done();\n        }, 10);\n      },\n      afterChildProcess(_, done) {\n        setTimeout(function() {\n          globals.calls++;\n          done();\n        }, 15);\n      },\n      reporter(_, cb) {\n        assert.strictEqual(globals.calls, 20);\n        cb();\n      }\n    };\n\n    return runTests(testsPath, settings({\n      output: false,\n      use_child_process: true,\n      globals\n    }));\n  });\n\n  it('test global async child process hooks - worker thread',  function() {\n    mockery.registerMock('./worker-process.js', class WorkerProcess {\n      static get isWorkerThread() {\n        return true;\n      }\n    });\n    const processPort = process.port;\n    process.port = {\n      postMessage: function(){}\n    };\n\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    const globals = {\n      calls: 0,\n      beforeChildProcess(_, done) {\n        setTimeout(function() {\n          globals.calls++;\n          done();\n        }, 10);\n      },\n      afterChildProcess(_, done) {\n        setTimeout(function() {\n          globals.calls++;\n          done();\n        }, 15);\n      },\n      reporter(_, cb) {\n        assert.strictEqual(globals.calls, 20);\n        process.port = processPort;\n        cb();\n      }\n    };\n\n    return runTests(testsPath, settings({\n      output: false,\n      use_child_process: false,\n      globals\n    }));\n  });\n \n});\n"
  },
  {
    "path": "test/src/runner/testRunWithGlobalReporter.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunWithGlobalReporter', function() {\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('testRunWithGlobalReporter', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    const globals = {\n      reporterCount: 0\n    };\n\n    return runTests(testsPath, settings({\n      globals,\n      globals_path: path.join(__dirname, '../../extra/external-globals.js'),\n      output_folder: false\n    }))\n      .then(err => {\n        assert.strictEqual(globals.reporterCount, 1);\n      });\n  });\n\n  it('testRunner with global async reporter', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    let reporterCount = 0;\n\n    return runTests(testsPath, settings({\n      globals: {\n        reporter(results, cb) {\n          assert.ok('modules' in results);\n          reporterCount++;\n          cb();\n        }\n      },\n      output_folder: false\n    }))\n      .catch(err => (err))\n      .then(_ => {\n        assert.strictEqual(reporterCount, 1);\n      });\n  });\n\n  it('testRunner with global async reporter and timeout error', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    let reporterCount = 0;\n\n    return runTests(testsPath, settings({\n      globals: {\n        customReporterCallbackTimeout: 10,\n        reporter(results, cb) {\n          assert.ok('modules' in results);\n          reporterCount++;\n        }\n      },\n      output_folder: false\n    })).then(_ => {\n      assert.strictEqual(reporterCount, 1);\n    }).catch(err => {\n      assert.strictEqual(err.message, 'Timeout while waiting for the custom reporter to finish.');\n    });\n  });\n\n  it('to check skipped count in global reporter', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/globalreporterskippedcount/sample.js');\n    let reporterCount = 0;\n\n    return runTests(testsPath, settings({\n      globals: {\n        reporter(results, cb) {\n          assert.strictEqual(results.skipped, 2);\n          assert.strictEqual(results.modules.sample.skippedCount, 2);\n          reporterCount++;\n          cb();\n        }\n      },\n      output_folder: false\n    })).then(_ => {\n      assert.strictEqual(reporterCount, 1);\n    }).catch(err => (err));\n  });\n\n\n  it('test plugin global reporter', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    const pluginPath = path.join(__dirname, '../../extra/plugin');\n    const globals = {\n      reporterCount: 0,\n      reporter(results, done) {\n        this.reporterCount++;\n        done();\n      }\n    };\n\n    return runTests(testsPath, settings({\n      plugins: [pluginPath],\n      globals,\n      output_folder: false\n    }))\n      .then(err => {\n        assert.strictEqual(globals.reporterCount, 2);\n      });\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunWithHooks.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\nconst mockery = require('mockery');\n\ndescribe('testRunWithHooks', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  afterEach(function() {\n    Object.keys(require.cache).filter(i => i.includes('/sampletests')).forEach(function(module) {\n      delete require.cache[module];\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  [\n    'before',\n    'beforeAsync',\n    'beforeWithClient',\n    'beforeEach',\n    'beforeEachAsync',\n    'beforeEachWithClient',\n    'beforeEachAsyncWithClient',\n    'beforeEachAsyncWithClientMultiple',\n    'afterEach',\n    'afterEachAsync',\n    'afterEachWithClient',\n    'after',\n    'afterAsync',\n    'afterWithClient'\n  ].forEach(function(hook) {\n    it(`testRunner with ${hook} hook and explicit callback error`, function() {\n      const provideErrorTestPath = path.join(__dirname, '../../asynchookstests/async-provide-error/' + hook + '.js');\n      const expectedErrorMessage = 'Provided error ' + hook;\n\n      const globals = {\n        calls: 0,\n        asyncHookTimeout: 50,\n\n        reporter(results) {\n          assert.ok(results.lastError instanceof Error);\n          assert.ok(results.lastError.message.includes(expectedErrorMessage));\n\n          if (hook.indexOf('before') === 0) {\n            assert.strictEqual(results.assertions, 0);\n          }\n          assert.strictEqual(results.errors, 1);\n        }\n      };\n\n      return runTests(provideErrorTestPath, settings({\n        globals\n      }));\n    });\n  });\n\n  [\n    'before',\n    'beforeAsync',\n    'beforeWithClient',\n    'beforeEach',\n    'beforeEachAsync',\n    'beforeEachWithClient',\n    'beforeEachAsyncWithClient',\n    'beforeEachAsyncWithClientMultiple',\n    'afterEach',\n    'afterEachAsync',\n    'afterEachWithClient',\n    'after',\n    'afterAsync',\n    'afterWithClient'\n  ].forEach(function(hook) {\n    it(`testRunner with ${hook} hook and explicit callback error with --fail-fast argument`, function() {\n      const source = [\n        path.join(__dirname, '../../asynchookstests/async-provide-error/' + hook + '.js'),\n        path.join(__dirname, '../../sampletests/async/test/sample.js')\n      ];\n\n      const globals = {\n        calls: 0,\n        asyncHookTimeout: 50,\n\n        reporter(results) {\n          assert.strictEqual(Object.keys(results.modules).length, 1);\n        }\n      };\n\n      return runTests({\n        source,\n        'fail-fast': true\n      }, settings({\n        globals\n      })).catch(err => {\n        return err;\n      }).then(err => {\n        assert.ok(err instanceof Error);\n        if (err.name === 'ERR_ASSERTION') {\n          throw err;\n        }\n      });\n    });\n  });\n\n  [\n    'before',\n    'beforeAsync',\n    'beforeWithClient',\n    'beforeEach',\n    'beforeEachAsync',\n    'beforeEachWithClient',\n    'beforeEachAsyncWithClient',\n    'beforeEachAsyncWithClientMultiple',\n    'afterEach',\n    'afterEachAsync',\n    'afterEachWithClient',\n    'after',\n    'afterAsync',\n    'afterWithClient'\n  ].forEach(function(hook) {\n    it(`testRunner with ${hook} hook and explicit callback error without fail-fast argument`, function() {\n      const source = [\n        path.join(__dirname, '../../asynchookstests/async-provide-error/' + hook + '.js'),\n        path.join(__dirname, '../../sampletests/async/test/sample.js')\n      ];\n\n      const globals = {\n        calls: 0,\n        asyncHookTimeout: 50,\n\n        reporter(results) {\n          assert.strictEqual(Object.keys(results.modules).length, 2);\n        }\n      };\n\n      return runTests({\n        source\n      }, settings({\n        globals\n      }));\n    });\n  });\n\n  it('test run with async before and after', function() {\n    const globals = {\n      calls: 0,\n      reporter(results) {\n        assert.strictEqual(globals.calls, 2);\n        assert.ok(`test${path.sep}sample` in results.modules);\n        assert.ok('demoTestAsync' in results.modules[`test${path.sep}sample`].completed);\n      }\n    };\n\n    const testsPath = path.join(__dirname, '../../sampletests/async');\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('test run with async afterEach', function() {\n    const origExit = process.exit;\n    process.exit = function() {};\n\n    const globals = {\n      calls: 0,\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n        assert.ok('sample' in results.modules);\n        assert.ok('demoTestMixed' in results.modules.sample.completed);\n        process.exit = origExit;\n      }\n    };\n\n    const testsPath = path.join(__dirname, '../../sampletests/mixed');\n\n    return runTests(testsPath, settings({\n      seleniumPort: 10195,\n      globals\n    }));\n  });\n\n  it('testRunner async with before and after', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after');\n    const globals = {\n      calls: 0,\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n        assert.strictEqual(globals.calls, 19);\n        assert.ok('sampleWithBeforeAndAfter' in results.modules);\n\n        const result = results.modules.sampleWithBeforeAndAfter.completed;\n        assert.ok('demoTestAsyncOne' in result);\n        assert.ok('demoTestAsyncTwo' in result);\n        assert.ok(!('beforeEach' in result));\n        assert.ok(!('before' in result));\n        assert.ok(!('afterEach' in result));\n        assert.ok(!('after' in result));\n        assert.ok('syncBeforeAndAfter' in results.modules);\n        assert.ok('demoTestAsyncOne' in result);\n        assert.ok('demoTestAsyncTwo' in result);\n        assert.ok(!('beforeEach' in result));\n        assert.ok(!('before' in result));\n        assert.ok(!('afterEach' in result));\n        assert.ok(!('after' in result));\n      }\n    };\n\n    return runTests(testsPath, settings({\n      seleniumPort: 10195,\n      globals\n    }));\n  });\n\n  it('testRunner before and after without callback', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after/sampleWithBeforeAndAfterNoCallback.js');\n    const globals = {\n      calls: 0,\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n        assert.strictEqual(globals.calls, 2);\n        assert.ok('sampleWithBeforeAndAfterNoCallback' in results.modules);\n      }\n    };\n\n    return runTests(testsPath, settings({\n      seleniumPort: 10195,\n      globals\n    }));\n  });\n\n  it('testRunner with assertion failed in after hook', function() {\n    const testsPath = path.join(__dirname, '../../asynchookstests/sampleWithAssertionFailedInAfter.js');\n    const globals = {\n      calls: 0,\n      reporter(results) {\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.lastError.name, 'NightwatchAssertError');\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      seleniumPort: 10195,\n      globals\n    }));\n  });\n\n  it('testRunner with --testcase and before and after', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/before-after/syncBeforeAndAfter.js');\n    const globals = {\n      calls: 0,\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n\n        assert.strictEqual(globals.calls, 4);\n        const result = results.modules.syncBeforeAndAfter.completed;\n        assert.ok('demoTestSyncOne' in result);\n        assert.ok(!('beforeEach' in result));\n        assert.ok(!('before' in result));\n        assert.ok(!('afterEach' in result));\n        assert.ok(!('after' in result));\n      }\n    };\n\n\n    return runTests({\n      _source: [testsPath],\n      testcase: 'demoTestSyncOne'\n    }, settings({\n      seleniumPort: 10195,\n      globals,\n      output_folder: false\n    }));\n  });\n\n  it('testRunner with command inside before', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/beforewithcommand/commandInsideBefore.js');\n    const globals = {\n      calls: 0,\n      reporter(results) {\n        assert.ok(results.lastError instanceof Error);\n\n        assert.strictEqual(globals.calls, 6);\n        const result = results.modules.commandInsideBefore.completed;\n        // assert.ok('demoTestSyncOne' in result);\n        assert.ok(!('beforeEach' in result));\n        assert.ok(!('before' in result));\n        assert.ok(!('afterEach' in result));\n        assert.ok(!('after' in result));\n      }\n    };\n\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      seleniumPort: 10195,\n      globals,\n      output_folder: false\n    }));\n  });\n\n  it('testRunner with command inside before with 0 parameters', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/beforewithcommand/commandInsideBeforeWithNoParams.js');\n    const globals = {\n      calls: 0,\n      reporter(results) {\n        assert.ok(results.lastError instanceof Error);\n\n        assert.strictEqual(globals.calls, 6);\n        const result = results.modules.commandInsideBeforeWithNoParams.completed;\n        // assert.ok('demoTestSyncOne' in result);\n        assert.ok(!('beforeEach' in result));\n        assert.ok(!('before' in result));\n        assert.ok(!('afterEach' in result));\n        assert.ok(!('after' in result));\n      }\n    };\n\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      seleniumPort: 10195,\n      globals,\n      output_folder: false\n    }));\n  });\n\n  it('testRunWithAsyncHooks', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withasynchooks');\n    const globals = {\n      calls: 0,\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n\n        assert.strictEqual(globals.calls, 7);\n      }\n    };\n\n    return runTests(testsPath, settings({\n      custom_commands_path: path.join(__dirname, '../../extra/commands'),\n      globals\n    }));\n  });\n\n  it('test async afterEach hook timeout error', function() {\n    const testsPath = path.join(__dirname, '../../asynchookstests/afterEach-timeout');\n    const globals = {\n      calls: 0,\n      asyncHookTimeout: 10,\n      reporter(results) {\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.lastError.message, 'done() callback timeout of 10ms was reached while executing \"afterEach\". ' +\n          'Make sure to call the done() callback when the operation finishes.');\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('testRunner passes testEnvSettings to global before hook', function() {\n    // Mock analytics to prevent cleanup errors\n    mockery.enable({useCleanCache: true, warnOnUnregistered: false});\n    mockery.registerMock('../../utils/analytics.js', {\n      updateSettings: () => {},\n      updateLogger: () => {},\n      collectEvent: () => {},\n      __flush: () => Promise.resolve()\n    });\n\n    try {\n      const CliRunner = common.require('runner/cli/cli.js');\n      \n      let beforeHookCalled = false;\n      let beforeHookArgs = null;\n      \n      // Create a minimal CliRunner instance\n      const runner = Object.create(CliRunner.prototype);\n      \n      // Set up required properties\n      runner.test_settings = { \n        globals: {},\n        test_runner: {type: 'mocha'},\n        desiredCapabilities: {real_mobile: false, avd: null},\n        usage_analytics: {enabled: false}\n      };\n      \n      // Mock testEnvSettings property \n      const mockTestEnvSettings = { \n        default: {selenium: {port: 4444}, globals: {}}\n      };\n      \n      Object.defineProperty(runner, 'testEnvSettings', {\n        get: function() { return mockTestEnvSettings }\n      });\n      \n      // Mock runGlobalHook to capture arguments\n      runner.runGlobalHook = function(hookName, args) {\n        if (hookName === 'before') {\n          beforeHookCalled = true;\n          beforeHookArgs = args;\n          \n          // Verify the enhancement: both test_settings and testEnvSettings are passed\n          assert.ok(Array.isArray(args), 'before hook should receive an array of arguments');\n          assert.strictEqual(args.length, 2, 'before hook should receive exactly 2 arguments');\n          assert.strictEqual(args[0], runner.test_settings, 'first argument should be test_settings');\n          assert.strictEqual(args[1], mockTestEnvSettings, 'second argument should be testEnvSettings');\n        }\n\n        return Promise.resolve();\n      };\n      \n      // Mock other required methods\n      runner.getTestsFiles = () => Promise.resolve({});\n      runner.createTestRunner = () => Promise.resolve();\n      runner.setExitCode = () => {};\n      runner.testRunner = {run: () => Promise.resolve({})};\n      \n      // Call the runTests method\n      return runner.runTests().then(() => {\n        assert.ok(beforeHookCalled, 'before hook should have been called');\n        assert.ok(beforeHookArgs, 'before hook arguments should have been captured');\n        assert.deepEqual(beforeHookArgs[0], runner.test_settings, 'before hook arguments contains test_settings');\n        assert.deepEqual(beforeHookArgs[1], mockTestEnvSettings, 'before hook arguments contains testEnvSettings');\n      });\n    } finally {\n      mockery.deregisterAll();\n      mockery.resetCache();\n      mockery.disable();\n    }\n  });\n});\n\n"
  },
  {
    "path": "test/src/runner/testRunWithMultipleSources.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunWithMultipleSources', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('testRunWithMultipleSourceFiles', function() {\n    let testsPath = [\n      path.join(__dirname, '../../sampletests/async/test/sample.js'),\n      path.join(__dirname, '../../sampletests/before-after/sampleSingleTest.js')\n    ];\n    let globals = {\n      calls: 0,\n      reporter(results) {\n        assert.strictEqual(globals.calls, 7);\n        assert.strictEqual(Object.keys(results.modules).length, 2);\n        assert.ok('sample' in results.modules);\n        assert.ok('sampleSingleTest' in results.modules);\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('testRunWithSourceFilesAndFolders', function() {\n    let testsPath = [\n      path.join(__dirname, '../../sampletests/async/test/sample.js'),\n      path.join(__dirname, '../../sampletests/before-after/')\n    ];\n\n    let globals = {\n      calls: 0,\n      reporter(results) {\n        assert.strictEqual(globals.calls, 21);\n        assert.strictEqual(Object.keys(results.modules).length, 5);\n        assert.ok('sample' in results.modules);\n        assert.ok('sampleSingleTest' in results.modules);\n        assert.ok('sampleWithBeforeAndAfter' in results.modules);\n        assert.ok('syncBeforeAndAfter' in results.modules);\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('testRunner with multiple src_folders value', function() {\n    let testsPath = [\n      path.join(__dirname, '../../sampletests/async/'),\n      path.join(__dirname, '../../sampletests/simple/')\n    ];\n\n    let globals = {\n      calls: 0,\n      reporter(results) {\n        assert.ok(`async${path.sep}test${path.sep}sample` in results.modules);\n        assert.ok(`simple${path.sep}test${path.sep}sample` in results.modules);\n        assert.strictEqual(Object.keys(results.modules).length, 2);\n      }\n    };\n\n    return runTests(settings({\n      src_folders: testsPath,\n      globals\n    }));\n  });\n\n  it('testRunner with multiple src_folders value - with unit tests error', function() {\n    const mockery = require('mockery');\n    mockery.enable({useCleanCache: true, warnOnUnregistered: false});\n    mockery.registerMock('../process-listener.js', function() {\n      this.setTestRunner = function() {};\n      this.onuncaught = function(err) {};\n    });\n\n    let uncaughtErr = null;\n    process.on('uncaughtException', function(err) {\n      uncaughtErr = err;\n    });\n\n    const Client = common.require('index.js');\n\n    let testsPath = [\n      path.join(__dirname, '../../sampletests/async/'),\n      path.join(__dirname, '../../sampletests/unittests/')\n    ];\n\n    let globals = {\n      calls: 0,\n      reporter(results) {\n        assert.ok(`test${path.sep}sample` in results.modules);\n        assert.ok(`unittests${path.sep}sample` in results.modules);\n        assert.ok(`unittests${path.sep}sampleAnnotation` in results.modules);\n        assert.strictEqual(Object.keys(results.modules).length, 3);\n      }\n    };\n\n    return Client.runTests(settings({\n      src_folders: testsPath,\n      globals\n    })).then(_ => {\n      mockery.deregisterAll();\n      mockery.disable();\n      assert.ok(uncaughtErr instanceof TypeError);\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunWithServerErrors.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunWithServerErrors', function() {\n\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  afterEach(function() {\n    Object.keys(require.cache).filter(i => i.includes('/sampletests')).forEach(function(module) {\n      delete require.cache[module];\n    });\n  });\n\n  it('testRunner with 502 server errors', function() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '#element-server-error'\n      },\n      statusCode: 502,\n      contentType: 'text/html',\n      response: '<html>\\n<head>\\n<title>502 Bad Gateway</title>\\n</head>\\n<body>\\n</body></html>',\n      times: 6\n    });\n\n    const testsPath = path.join(__dirname, '../../sampletests/withservererrors');\n    const globals = {\n      calls: 0,\n      retryAssertionTimeout: 150,\n      waitForConditionTimeout: 150,\n      waitForConditionPollInterval: 50,\n      reporter(results, cb) {\n        assert.strictEqual(results.errmessages.length, 4);\n        assert.strictEqual(results.passed, 0);\n        assert.strictEqual(results.failed, 3);\n        assert.strictEqual(results.assertions, 3);\n        assert.strictEqual(results.errors, 4);\n        assert.strictEqual(results.skipped, 0);\n        const {completed} = results.modules.sampleTestWithServerError;\n        assert.ok(completed.demoTest.lastError.message.includes('502 Bad Gateway'), `Result: ${completed.demoTest.lastError.message}`);\n\n        cb();\n      }\n    };\n\n    return runTests({\n      _source: [testsPath]\n    }, settings({\n      output: false,\n      skip_testcases_on_fail: false,\n      report_command_errors: true,\n      disable_error_log: 0,\n      globals,\n      webdriver: {\n        internal_server_error_retry_interval: 100\n      }\n    }));\n  });\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunWithTags.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunWithTags', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  afterEach(function() {\n    Object.keys(require.cache).filter(i => i.includes('/sampletests')).forEach(function(module) {\n      delete require.cache[module];\n    });\n  });\n\n  it('testRunner with tags', function() {\n    const testsPath = path.join(__dirname, '../../sampletests');\n\n    return runTests({\n      _source: [testsPath],\n      tag: ['browser']\n    }, settings({\n      output: false,\n      disable_typescript: true,\n      globals: {\n        reporter(results) {\n          assert.strictEqual(Object.keys(results.modules).length, 1);\n          assert.ok('demoTagTest' in results.modules[`tagswithbrowserobject${path.sep}sample`].completed);\n        }\n      }\n    }));\n  });\n\n  it('testRunWithTags', function() {\n    let testsPath = path.join(__dirname, '../../sampletests');\n\n    return runTests(testsPath, settings({\n      output: false,\n      disable_typescript: true,\n      globals: {\n        waitForConditionPollInterval: 10,\n        waitForConditionTimeout: 11,\n        retryAssertionTimeout: 10,\n        reporter(results) {\n          assert.strictEqual(Object.keys(results.modules).length, 3);\n          assert.ok('demoTagTest' in results.modules[`tags${path.sep}sample`].completed);\n          assert.ok('otherDemoTagTest' in results.modules[`withsubfolders${path.sep}tags${path.sep}sampleTags`].completed);\n          assert.ok('demoTest' in results.modules[`withdescribe${path.sep}failures${path.sep}sampleSkipTestcases`].completed);\n        }\n      },\n      tag_filter: ['login']\n    }));\n  });\n\n  it('testRunWithTagsAndFilterEmpty', function() {\n    let testsPath = path.join(__dirname, '../../sampletests');\n\n    return runTests(testsPath, settings({\n      globals: {\n      },\n      filter: 'syncnames/*',\n      tag_filter: ['login']\n    }))\n      .catch(err => {\n        assert.ok(err instanceof Error);\n        assert.ok(err.message.includes('No tests defined!'));\n      });\n  });\n\n  it('testRunWithTagsAndFilterNotEmpty', function() {\n    let testsPath = path.join(__dirname, '../../sampletests');\n\n    return runTests(testsPath, settings({\n      globals: {\n        reporter(results) {\n          assert.ok('demoTagTest' in results.modules[`tags${path.sep}sample`].completed);\n          assert.strictEqual(Object.keys(results.modules).length, 1);\n        }\n      },\n      filter: 'tags/*',\n      tag_filter: ['login']\n    }));\n  });\n\n  it('testRunWithSkipTagsAndFilterNotEmpty', function() {\n    let testsPath = path.join(__dirname, '../../sampletests');\n\n    return runTests({\n      _source: [testsPath],\n      skiptags: ['logout']\n    }, settings({\n      globals: {\n        reporter(results) {\n          assert.ok('demoTagTest' in results.modules[`tags${path.sep}sample`].completed);\n          assert.strictEqual(Object.keys(results.modules).length, 1);\n        }\n      },\n      filter: '**/tags/*'\n    }));\n  });\n\n  it('testRun with filter and skiptags no matches', function() {\n    let testsPath = path.join(__dirname, '../../sampletests');\n\n    return runTests({\n      _source: [testsPath],\n      skiptags: ['logout', 'login']\n    }, settings({\n      globals: {\n        reporter(results) {\n        }\n      },\n      filter: '**/tags/*'\n    })).catch(err => {\n      return err;\n    }).then(err => {\n      assert.ok(err instanceof Error);\n      assert.ok(err.message.includes('No tests defined! using source folder'), err.message + '\\n' + err.stack);\n      assert.ok(err.detailedErr.includes('- using path filter: **/tags/*'));\n      assert.ok(err.detailedErr.includes('- using skiptags filter: logout,login'));\n    });\n  });\n\n  it('testRunWithTagsAndSkipTags', function() {\n    let testsPath = path.join(__dirname, '../../sampletests');\n\n    return runTests({\n      _source: [testsPath],\n      skiptags: ['other']\n    }, settings({\n      output: false,\n      disable_typescript: true,\n      globals: {\n        reporter(results) {\n          assert.strictEqual(Object.keys(results.modules).length, 2);\n          assert.ok('otherDemoTagTest' in results.modules[`withsubfolders${path.sep}tags${path.sep}sampleTags`].completed);\n        }\n      },\n      tag_filter: ['login']\n    }));\n  });\n\n  it('testRunner with tags and skip tags no matches', function() {\n    let testsPath = path.join(__dirname, '../../sampletests');\n\n    return runTests({\n      _source: [testsPath],\n      skiptags: ['login']\n    }, settings({\n      globals: {},\n      output: false,\n      tag_filter: ['other']\n    })).catch(err => {\n      return err;\n    }).then(err => {\n      assert.ok(err instanceof Error);\n      assert.ok(err.message.includes('No tests defined! using source folder'), err.message + '\\n' + err.stack);\n      assert.ok(err.detailedErr.includes('- using tags filter: other'));\n      assert.ok(err.detailedErr.includes('- using skiptags filter: login'));\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunWithVerify.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\nconst originalCwd = process.cwd();\ndescribe('testRunWithVerify', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => done());\n  });\n\n  beforeEach(function(done) {\n    process.chdir(path.join(__dirname, '../../sampletests/'));\n    done();\n  });\n\n  afterEach(function(done) {\n    process.chdir(originalCwd);\n    done();\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('using verify in tests with simple failures', function() {\n    return runTests({\n      _source: ['./withverify/verifySampleFailures.js']\n    }, settings({\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter(results, cb) {\n          assert.ok('verifySampleFailures' in results.modules);\n          assert.strictEqual(results.passed, 2);\n          assert.strictEqual(results.failed, 2);\n          assert.strictEqual(results.assertions, 4);\n          assert.strictEqual(results.skipped, 0);\n\n          cb();\n        }\n      }\n    }));\n  });\n\n  it('using verify within perform in tests', function() {\n    return runTests({\n      _source: ['./withverify/verifyWithinPerform.js']\n    }, settings({\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter(results, cb) {\n          assert.ok('verifyWithinPerform' in results.modules);\n          assert.strictEqual(results.passed, 0);\n          assert.strictEqual(results.failed, 2);\n          assert.strictEqual(results.assertions, 2);\n\n          cb();\n        }\n      }\n    }));\n  });\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunner.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst Globals = require('../../lib/globals.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst Runner = common.require('runner/runner.js');\nconst Settings = common.require('settings/settings.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunner', function() {\n  const emptyPath = path.join(__dirname, '../../sampletests/empty/testdir');\n\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      fs.mkdir(emptyPath, function(err) {\n        if (err) {\n          return done();\n        }\n        done();\n      });\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, function() {\n      fs.rmdir(emptyPath, function(err) {\n        if (err) {\n          return done();\n        }\n        done();\n      });\n    });\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('testRunEmptyFolder', function(done) {\n    Globals\n      .startTestRunner(emptyPath, {\n        output_folder: false\n      })\n      .catch(err => {\n        assert.ok(err instanceof Error);\n        if (err.message !== `No tests defined! using source folder: ${emptyPath}`) {\n          done(err);\n        } else {\n          done();\n        }\n      });\n  });\n\n  it('testRunEmptySubFolder', function(done) {\n    let testsPath = path.dirname(emptyPath);\n\n    Globals\n      .startTestRunner(testsPath, {\n        output_folder: false\n      })\n      .catch(err => {\n        assert.ok(err instanceof Error);\n        if (err.message !== `No tests defined! using source folder: ${testsPath}`) {\n          done(err);\n        } else {\n          done();\n        }\n      });\n  });\n\n  it('testRunNoSrcFoldersArgument', function() {\n    let settings = Settings.parse({\n      output_folder: false\n    });\n\n    assert.throws(function() {\n      Runner.readTestSource(settings);\n    }, /No test source specified, please check \"src_folders\" config/);\n  });\n\n  it('testRunSimple', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/simple');\n    let globals = {\n      reporter(results) {\n        assert.ok(`test${path.sep}sample` in results.modules);\n        assert.ok('demoTest' in results.modules[`test${path.sep}sample`].completed);\n\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('readTestSource with glob pattern', async function(){\n    const modules =  await Runner.readTestSource({\n      src_folders: [path.join(__dirname, '../../sampletests/srcfolders/*.js')]\n    },  {});\n    assert.deepStrictEqual(modules, [path.join(__dirname, '../../sampletests/srcfolders/other_sample.js')]);\n  });\n\n  it('readTestSource with glob pattern and normal folder', async function(){\n    const modules =  await Runner.readTestSource({\n      src_folders: [path.join(__dirname, '../../sampletests/srcfolders/*.js'), path.join(__dirname, '../../sampletests/async/')]\n    },  {});\n    assert.deepStrictEqual(modules, [path.join(__dirname, '../../sampletests/srcfolders/other_sample.js'), path.join(__dirname, '../../sampletests/async/test/sample.js')]);\n  });\n\n  it('readTestSource with glob pattern that matches no file', async  function(){\n    await assert.rejects(async function() {\n      await Runner.readTestSource({\n        src_folders: [path.join(__dirname, '../../sampletests/srcfolders/nightwatch/*.js')]\n      },  {});\n    }, 'Should be rejected');\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerChaiExpect.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst Globals = require('../../lib/globals');\n\ndescribe('testRunnerChaiExpect', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('testRunWithChaiExpect', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withchaiexpect/sampleWithChai.js');\n    const Settings = common.require('settings/settings.js');\n    let settings = Settings.parse({\n      selenium: {\n        port: 10195,\n        host: 'localhost',\n        start_process: false\n      },\n      globals: {\n        test: assert,\n        reporter() {\n\n        }\n      },\n      output_folder: false,\n      tag_filter: null,\n      silent: false,\n      output: false\n    });\n\n    const Globals = require('../../lib/globals.js');\n\n    return Globals.startTestRunner(testsPath, settings)\n      .then(runner => {\n        assert.ok(runner.results.lastError instanceof Error);\n\n        const ex = runner.results.lastError;\n        assert.ok(ex.message.startsWith('expected [ { ELEMENT: \\'0\\' } ] to have a length of 2 but got 1'));\n\n        assert.strictEqual(runner.results.modules.sampleWithChai.tests, 3);\n        assert.strictEqual(runner.results.modules.sampleWithChai.failures, 1);\n      });\n  });\n\n  it('test run with global expect()', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withchaiexpect/sampleWithGlobalExpect.js');\n\n    const Settings = common.require('settings/settings.js');\n    let settings = Settings.parse({\n      selenium: {\n        port: 10195,\n        host: 'localhost',\n        start_process: false\n      },\n      globals: {\n        test: assert,\n        reporter() {\n        }\n      },\n      output_folder: false,\n      silent: false,\n      output: false\n    });\n\n    const Globals = require('../../lib/globals.js');\n\n    return Globals.startTestRunner(testsPath, settings)\n      .then(runner => {\n        assert.ok(runner.results.lastError instanceof Error);\n\n        const ex = runner.results.lastError;\n        assert.strictEqual(ex.message, 'Property \".present\" is not available when asserting on non-element values.');\n\n        assert.strictEqual(runner.results.modules.sampleWithGlobalExpect.tests, 2);\n        assert.strictEqual(runner.results.modules.sampleWithGlobalExpect.errors, 1);\n      });\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerEndSessionOnFail.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst nock = require('nock');\nconst nocks = require('../../lib/nocks');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('test runner with end_session_on_fail flag', function() {\n\n  before(function(done) {\n    nocks.enable().cleanAll();\n    CommandGlobals.beforeEach.call(this, done);\n    \n  });\n\n  after(function(done) {\n    nocks.disable();\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n\n  it('session is not ended with end_on_sessiion_fail: false', function() {\n    let endSessionCalled = false;\n    const testFile = path.join(__dirname, '../../sampletests/withfailures/sample.js');\n\n    nocks.createSession()\n      .url()\n      .elementNotFound('#weblogin');\n   \n\n    nock('http://localhost:10195')\n      .delete('/wd/hub/session/1352110219202')\n      .reply(204, ()=> {\n        endSessionCalled = true;\n      \n        return '';\n      });\n\n    return runTests(testFile, settings({\n      enable_fail_fast: true,\n      end_session_on_fail: false,\n      globals: {\n        waitForConditionPollInterval: 5,\n        waitForConditionTimeout: 5,\n        retryAssertionTimeout: 1\n      }\n    })).catch(_ => {\n      assert.strictEqual(endSessionCalled, false);\n    });\n\n\n  });\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerEs6Async.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst MockServer = require('../../lib/mockserver.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst common = require('../../common.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunner ES6 Async', function () {\n  before(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function () {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n\n  it('test Runner with ES6 fluent api basic sample', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/es6await/basicSampleTest.js');\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/cookie/test_cookie',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: [{\n          name: 'test_cookie',\n          value: '123456',\n          path: '/',\n          domain: 'example.org',\n          secure: false,\n          class: 'org.openqa.selenium.Cookie',\n          hCode: 91423566\n        }]\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      postdata: '{\"using\":\"css selector\",\"value\":\"#badelement\"}',\n\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: null\n      })\n    }, false, true);\n\n    let globals = {\n      waitForConditionPollInterval: 150,\n      waitForConditionTimeout: 100,\n      retryAssertionTimeout: 150,\n\n      reporter(results) {\n        assert.ok('basicSampleTest' in results.modules);\n\n        const {lastError} = results.modules.basicSampleTest;\n        if (lastError && lastError.name !== 'NightwatchAssertError') {\n          throw results.modules.basicSampleTest.lastError;\n        }\n      }\n    };\n\n    return runTests(testsPath, settings({\n      skip_testcases_on_fail: false,\n      output: false,\n      globals\n    }));\n  });\n\n  it('test Runner with ES6 async/await tests basic sample', function () {\n    let testsPath = path.join(__dirname, '../../sampletests/es6await/selenium');\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/cookie',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: [{\n          name: 'test_cookie',\n          value: '123456',\n          path: '/',\n          domain: 'example.org',\n          secure: false,\n          class: 'org.openqa.selenium.Cookie',\n          hCode: 91423566\n        }]\n      })\n    }, true);\n\n    let globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        assert.ok(`failures${path.sep}sampleWithFailures` in results.modules, 'sampleWithFailures module not found in results');\n        assert.ok('basicSampleTestSelenium' in results.modules);\n        if (results.modules.basicSampleTestSelenium.lastError) {\n          throw results.modules.basicSampleTestSelenium.lastError;\n        }\n\n        if (results.modules[`failures${path.sep}sampleWithFailures`].completed.asyncGetCookiesTest.lastError) {\n          throw results.modules[`failures${path.sep}sampleWithFailures`].completed.asyncGetCookiesTest.lastError;\n        }\n\n        assert.ok(`failures${path.sep}sampleWithFailures` in results.modules);\n        assert.strictEqual(results.modules[`failures${path.sep}sampleWithFailures`].completed.verify.assertions.length, 2);\n\n        assert.ok(results.modules[`failures${path.sep}sampleWithFailures`].completed.verify.assertions[0].failure.includes('Expected \"is present\" but got: \"not present\"'));\n        assert.strictEqual(results.modules[`failures${path.sep}sampleWithFailures`].completed.verify.assertions[1].failure, false);\n        assert.strictEqual(results.modules[`failures${path.sep}sampleWithFailures`].completed.waitFor.failed, 1);\n\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.lastError.name, 'NightwatchAssertError');\n      }\n    };\n\n    return runTests(testsPath, settings({\n      skip_testcases_on_fail: false,\n      output: false,\n      globals\n    }));\n  });\n\n  it('test Runner with ES6 async/await tests getLog example', function () {\n    const testsPath = path.join(__dirname, '../../sampletests/es6await/selenium/getlog');\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it.skip('test Runner with ES6 async/await tests getText example', function () {\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 201,\n      postdata: JSON.stringify({\n        desiredCapabilities: {browserName: 'firefox', name: 'Get Text ES6'},\n        capabilities: {alwaysMatch: {browserName: 'firefox'}}\n      }),\n      response: JSON.stringify({\n        value: {\n          sessionId: '13521-10219-202',\n          capabilities: {\n            acceptInsecureCerts: false,\n            browserName: 'firefox',\n            browserVersion: '65.0.1'\n          }\n        }\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/url',\n      statusCode: 200,\n      response: JSON.stringify({\n        value: null\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '#element-selector'\n      },\n\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '13521-10219-202',\n        status: 0,\n        value: [{\n          'element-6066-11e4-a52e-4f735466cecf': '5cc459b8-36a8-3042-8b4a-258883ea642b'\n        }]\n      })\n    }, false, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/5cc459b8-36a8-3042-8b4a-258883ea642b/text',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'sample text value'\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/elements',\n      postdata: {\n        using: 'css selector',\n        value: '#signupSection'\n      },\n\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '13521-10219-202',\n        status: 0,\n        value: [{\n          'element-6066-11e4-a52e-4f735466cecf': '8b4a-258883ea642b'\n        }]\n      })\n    }, true, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/8b4a-258883ea642b/elements',\n      postdata: {\n        using: 'css selector',\n        value: '#helpBtn'\n      },\n\n      method: 'POST',\n      response: JSON.stringify({\n        sessionId: '13521-10219-202',\n        status: 0,\n        value: [{\n          'element-6066-11e4-a52e-4f735466cecf': '258883ea642b'\n        }]\n      })\n    }, true, true);\n\n    MockServer.addMock({\n      url: '/session/13521-10219-202/element/258883ea642b/text',\n      method: 'GET',\n      response: JSON.stringify({\n        value: 'help text value'\n      })\n    }, true);\n\n    const testsPath = path.join(__dirname, '../../sampletests/es6await/webdriver/getText');\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return runTests(testsPath, settings({\n      webdriver: {\n        host: 'localhost'\n      },\n      selenium_host: null,\n      output: false,\n      page_objects_path: [path.join(__dirname, '../../extra/pageobjects/pages')],\n      skip_testcases_on_fail: false,\n      globals\n    }));\n  });\n\n  it('test Runner with ES6 async commands', function () {\n    const testsPath = path.join(__dirname, '../../sampletests/es6await/selenium/getlog');\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('test runner with async expect failure', function() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/text',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'Barn owl'\n      })\n    }, true);\n\n    const testsPath = path.join(__dirname, '../../sampletests/asyncwithexpectfailures');\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 100,\n      retryAssertionTimeout: 150,\n      reporter(results) {\n        assert.strictEqual(results.assertions, 2);\n        assert.strictEqual(results.failed, 1);\n        assert.strictEqual(results.passed, 1);\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n\n  it('test runner async with element incorrect args', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/es6await/incorrect-element-args');\n\n    const globals = {\n      waitForConditionPollInterval: 50,\n      waitForConditionTimeout: 100,\n      retryAssertionTimeout: 150,\n\n      reporter(results) {\n        assert.strictEqual(results.errors, 1);\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.lastError.message, 'Error while running \"getElementProperty\" command: getElementProperty method expects 2 (or 3 if using implicit \"css selector\" strategy) arguments - 1 given.');\n        assert.strictEqual(results.lastError.rejectPromise, true);\n      }\n    };\n\n    return runTests(testsPath, settings({\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerHtmlOutput.js",
    "content": "const path = require('path');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\nconst {readFilePromise} = require('../../lib/utils.js');\nconst rimraf = require('rimraf');\nconst assert = require('assert');\nconst HtmlReporter = common.require('reporter/reporters/html.js');\nconst {mkpath} = common.require('utils');\nconst reportObject = require('../../extra/reportObject');\n\ndescribe('testRunnerHTMLOutput', function() {\n  const outputPath = 'output';\n\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => done());\n  });\n\n  beforeEach(function(done) {\n    mkpath(outputPath, done);\n  });\n\n  afterEach(function(done) {\n    rimraf(outputPath, done);\n  });\n\n  after(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  it('test Html Reporter output', function () {\n    const options = {\n      output_folder: outputPath\n    };\n\n    const adaptedResults = HtmlReporter.adaptResults(reportObject, options);\n\n    assert.ok(adaptedResults);\n    \n    const environments = adaptedResults.environments ;\n    const metadata = adaptedResults.metadata ;\n    const stats = adaptedResults.stats ;\n    assert.ok(environments);\n    assert.ok(metadata);\n    assert.ok(stats);\n\n    assert.strictEqual(Object.keys(environments).length, 2);\n    assert.ok(metadata.date);\n    assert.strictEqual(stats.total, 22);\n    assert.strictEqual(stats.failed, 3);\n    assert.strictEqual(stats.skipped, 2);\n    assert.strictEqual(stats.passed, 17);\n\n    const chromeEnv = environments['chrome'];\n    const firefoxEnv = environments['firefox'];\n\n    assert.ok(chromeEnv);\n    assert.strictEqual(chromeEnv.stats.passed, 10);\n    assert.strictEqual(chromeEnv.stats.failed, 1);\n    assert.strictEqual(chromeEnv.stats.skipped, 0);\n    assert.strictEqual(chromeEnv.stats.time, 79681);\n    assert.strictEqual(chromeEnv.metadata.platformName, 'mac os x');\n    assert.strictEqual(chromeEnv.metadata.browserName, 'chrome');\n    assert.strictEqual(chromeEnv.metadata.browserVersion, '111.0.5563.146');\n    assert.strictEqual(chromeEnv.metadata.device, 'desktop');\n    assert.strictEqual(chromeEnv.metadata.executionMode, 'local');\n\n    assert.ok(firefoxEnv);\n    assert.strictEqual(firefoxEnv.stats.passed, 7);\n    assert.strictEqual(firefoxEnv.stats.failed, 2);\n    assert.strictEqual(firefoxEnv.stats.skipped, 2);\n    assert.strictEqual(firefoxEnv.stats.time, 70498);\n    assert.strictEqual(firefoxEnv.metadata.platformName, 'mac');\n    assert.strictEqual(firefoxEnv.metadata.browserName, 'firefox');\n    assert.strictEqual(firefoxEnv.metadata.browserVersion, '111.0.1');\n    assert.strictEqual(firefoxEnv.metadata.device, 'desktop');\n    assert.strictEqual(firefoxEnv.metadata.executionMode, 'local');\n    \n    assert.strictEqual(stats.time, 94000);\n\n    assert.strictEqual(Object.keys(chromeEnv.modules).length, 10);\n    assert.strictEqual(Object.keys(chromeEnv.modules['ecosia'].completedSections).length, 5);\n    assert.strictEqual(chromeEnv.modules['ecosia'].seleniumLog, '/Users/vaibhavsingh/Dev/nightwatch/logs/ecosia_chromedriver.log');\n\n    const demoTestPass = chromeEnv.modules['ecosia'].completedSections['Demo test ecosia.org'];\n\n    assert.ok(demoTestPass);\n    assert.strictEqual(demoTestPass.commands.length, 7);\n    assert.strictEqual(demoTestPass.status, 'pass');\n\n    const demoTestFail = firefoxEnv.modules['chromeCDP_example'].completedSections['using CDP DOM Snapshot'];\n    assert.ok(demoTestFail);\n    assert.strictEqual(demoTestFail.commands.length, 4);\n    assert.strictEqual(demoTestFail.status, 'fail');\n\n  });\n\n  it('test run screenshots with html output and test failures', function () {\n\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withfailures')\n    ];\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'screendata'\n      })\n    }, true);\n\n\n    return runTests({source: testsPath, reporter: 'html'}, settings({\n      output_folder: outputPath,\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter: function (result) {\n          const failedTest = result.modulesWithEnv.default.sample.completedSections.demoTest.commands[2];\n          assert.ok(failedTest.screenshot && failedTest.screenshot.includes(`sample${path.sep}demoTest`));\n        }\n      },\n      screenshots: {\n        enabled: true,\n        on_failure: true,\n        on_error: true,\n        path: ''\n      }\n    }))\n      .then(_ => {\n        return readFilePromise(`${outputPath}${path.sep}nightwatch-html-report${path.sep}index.html`);\n      });\n  });\n\n  it('test html report folder with a folder format function', function () {\n\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withfailures')\n    ];\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: '<faketag>fakedata'\n      })\n    }, true);\n\n\n    return runTests({source: testsPath, reporter: 'html'}, settings({\n      output_folder: outputPath,\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter: function () {\n        }\n      },\n      reporter_options: {\n        folder_format: function() {\n          return Date.now().toString();\n        }\n      }\n    }))\n      .then(_ => {\n        return readFilePromise(`${outputPath}${path.sep}*${path.sep}nightwatch-html-report${path.sep}index.html`);\n      }).\n      then(_ => {\n      });\n  });\n\n  it('test html report file with a file format function', function () {\n\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withfailures')\n    ];\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: '<faketag>fakedata'\n      })\n    }, true);\n\n\n    return runTests({source: testsPath, reporter: 'html'}, settings({\n      output_folder: outputPath,\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter: function () {\n        }\n      },\n      reporter_options: {\n        filename_format: function() {\n          return 'test_report';\n        }\n      }\n    }))\n      .then(_ => {\n        return readFilePromise(`${outputPath}${path.sep}nightwatch-html-report${path.sep}test_report.html`);\n      }).\n      then(_ => {\n      }).catch((err) => {\n        console.log(err);\n      });\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerJsonOutput.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst rimraf = require('rimraf');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\nconst {mkpath} = common.require('utils');\n\ndescribe('testRunnerJsonOutput', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => done());\n  });\n\n  beforeEach(function(done) {\n    mkpath('output', function(err) {\n      if (err) {\n        return done(err);\n      }\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    rimraf('output', done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('testRunWithJsonOutput', function() {\n    let testsPath = [\n      path.join(__dirname, '../../sampletests/withsubfolders')\n    ];\n\n    return runTests({source: testsPath, reporter: 'json'}, settings({\n      output_folder: 'output',\n      silent: true,\n      globals: {reporter: function() {}}\n    }))\n      .then(_ => {\n        return readDirPromise(testsPath[0]);\n      })\n      .then(list => {\n        let simpleReportFile = path.resolve('output/simple/FIREFOX_TEST_firefox__sample.json');\n        let tagsReportFile = path.resolve('output/tags/FIREFOX_TEST_firefox__sampleTags.json');\n\n        assert.deepStrictEqual(list, ['simple', 'tags'], 'The subfolders have not been created.');\n        assert.ok(fileExistsSync(simpleReportFile), 'The simple report file was not created.');\n        assert.ok(fileExistsSync(tagsReportFile), 'The tags report file was not created.');\n\n        return require(simpleReportFile);\n      })\n      .then(data => {\n        assert.strictEqual(typeof data.report, 'object');\n        assert.strictEqual(data.report.reportPrefix, 'FIREFOX_TEST_firefox__');\n        assert.strictEqual(data.report.assertionsCount, 1);\n        assert.strictEqual(data.report.failedCount, 0);\n        assert.strictEqual(data.report.errorsCount, 0);\n        assert.strictEqual(data.report.passedCount, 1);\n        assert.strictEqual(data.report.tests, 1);\n        assert.strictEqual(data.report.errmessages.length, 0);\n        assert.strictEqual(Object.keys(data.report.completed)[0], 'simpleDemoTest');\n        assert.strictEqual(data.name, 'sample');\n        assert.strictEqual(Array.isArray(data.httpOutput), true);\n\n        assert.strictEqual(data.report.modulePath.endsWith(path.join(\n          'test', 'sampletests', 'withsubfolders', 'simple', 'sample.js'\n        )), true);\n      });\n  });\n});\n\nfunction readDirPromise(dirName) {\n  return new Promise(function(resolve, reject) {\n    fs.readdir(dirName, function(err, result) {\n      if (err) {\n        return reject(err);\n      }\n\n      resolve(result);\n    });\n  });\n}\n\n// util to replace deprecated fs.existsSync\nfunction fileExistsSync(path) {\n  try {\n    fs.statSync(path);\n\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n"
  },
  {
    "path": "test/src/runner/testRunnerJunitOutput.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\nconst {readFilePromise, readDirPromise} = require('../../lib/utils.js');\nconst {mkpath} = common.require('utils');\nconst rimraf = require('rimraf');\n\ndescribe('testRunnerJUnitOutput', function() {\n\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, function() {\n      done();\n    });\n  });\n\n  beforeEach(function(done) {\n    mkpath('output', function(err) {\n      if (err) {\n        return done(err);\n      }\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    rimraf('output', done);\n  });\n\n  it('test run screenshots with jUnit output and test failures', function () {\n\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withfailures')\n    ];\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'screendata'\n      })\n    }, true);\n\n\n    return runTests(testsPath, settings({\n      output_folder: 'output',\n      reporter: 'junit',\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter: function () {\n        }\n      },\n      screenshots: {\n        enabled: true,\n        on_failure: true,\n        on_error: true,\n        path: ''\n      }\n    }))\n      .then(_ => {\n        return readFilePromise(`output${path.sep}FIREFOX_TEST_firefox__sample.xml`);\n      })\n      .then(data => {\n        const content = data.toString();\n        assert.ok(content.indexOf('<system-out>[[ATTACHMENT|') > 0);\n      });\n  });\n\n  it('testRun with jUnit output and errors', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/witherrors')\n    ];\n\n    return runTests(testsPath, settings({\n      output_folder: 'output',\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter(results) {\n          assert.strictEqual(results.assertions, 0);\n          assert.strictEqual(results.errmessages.length, 1);\n          assert.strictEqual(results.failed, 0);\n          assert.strictEqual(results.errors, 1);\n          assert.ok(results.lastError instanceof Error);\n          assert.ok(results.lastError.message.startsWith('Error in test script'));\n          assert.strictEqual(typeof results.modules.sampleWithError, 'object');\n          assert.strictEqual(results.modules.sampleWithError.assertionsCount, 0);\n          assert.strictEqual(results.modules.sampleWithError.errors, 1);\n          assert.strictEqual(results.modules.sampleWithError.failedCount, 0);\n          assert.strictEqual(results.modules.sampleWithError.testsCount, 1);\n        }\n      },\n      screenshots: {\n        enabled: false\n      }\n    }))\n      .then(_ => {\n        return readFilePromise('output/FIREFOX_TEST_firefox__sampleWithError.xml');\n      })\n      .then(data => {\n        const content = data.toString();\n        assert.ok(content.includes('<error message=\"Error in test script\" type=\"error\">'), 'Report should contain error message');\n        assert.ok(content.includes('sampleWithError.js'), 'Report should contain stackTrace');\n        assert.ok(content.includes('<system-err>'), 'Report should also contain <system-err>');\n      });\n  });\n\n  it('testRun with jUnit output and failures in before hook', function () {\n    const testsPath = [\n      path.join(__dirname, '../../asynchookstests/sampleWithAssertionFailedInBefore.js')\n    ];\n\n    return runTests(testsPath, settings({\n      output_folder: 'output',\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter(results) {\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errmessages.length, 1);\n          assert.strictEqual(results.failed, 1);\n          assert.ok(results.lastError instanceof Error);\n          assert.ok(results.lastError.message.startsWith('Failed [equal]: (0 == 1)'), results.lastError.message);\n          assert.strictEqual(typeof results.modules.sampleWithAssertionFailedInBefore, 'object');\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInBefore.assertionsCount, 1);\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInBefore.errmessages.length, 1);\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInBefore.failedCount, 1);\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInBefore.skippedAtRuntime.length, 0);\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInBefore.skipped.length, 0);\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInBefore.completed['demo test async'].assertions.length, 0);\n        }\n      },\n      screenshots: {\n        enabled: false\n      }\n    }))\n      .then(_ => {\n        return readFilePromise('output/FIREFOX_TEST_firefox__sampleWithAssertionFailedInBefore.xml');\n      })\n      .then(data => {\n        const content = data.toString();\n        assert.ok(content.includes('<system-err>'));\n        assert.ok(content.indexOf('Failed [equal]: (0 == 1) - expected &#34;1&#34; but got: &#34;0&#34;') > 0, 'Report should contain failure');\n        assert.ok(content.indexOf('sampleWithAssertionFailedInBefore.js') > -1, 'Report should contain stack trace');\n      });\n  });\n\n  it('testRun with jUnit output and errors in after hook', function () {\n    const testsPath = [\n      path.join(__dirname, '../../asynchookstests/sampleWithAssertionFailedInAfter.js')\n    ];\n\n    return runTests(testsPath, settings({\n      output_folder: 'output',\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter: function (results) {\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errmessages.length, 1);\n          assert.strictEqual(results.failed, 1);\n          assert.ok(results.lastError instanceof Error);\n          assert.ok(results.lastError.message.startsWith('Failed [equal]: (0 == 1)'), results.lastError.message);\n          assert.strictEqual(typeof results.modules.sampleWithAssertionFailedInAfter, 'object');\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInAfter.assertionsCount, 1);\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInAfter.errmessages.length, 1);\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInAfter.failedCount, 1);\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInAfter.skippedAtRuntime.length, 0);\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInAfter.skipped.length, 0);\n          assert.strictEqual(results.modules.sampleWithAssertionFailedInAfter.completed.demoTestAsyncOne.assertions.length, 0);\n        }\n      },\n      screenshots: {\n        enabled: false\n      }\n    }))\n      .then(_ => {\n        return readFilePromise('output/FIREFOX_TEST_firefox__sampleWithAssertionFailedInAfter.xml');\n      })\n      .then(data => {\n        const content = data.toString();\n        assert.ok(content.includes('<system-err>'), 'Report should contain <system-err>');\n        assert.ok(content.includes('Failed [equal]: (0 == 1) - expected &#34;1&#34; but got: &#34;0&#34;'), 'Report should contain Failed [equal]: (0 == 1)');\n        assert.ok(content.indexOf('sampleWithAssertionFailedInAfter.js') > -1, 'Report should contain stack trace');\n      });\n  });\n\n  it('testRun with jUnit output and failures in testcase and after hook', function () {\n    const testsPath = [\n      path.join(__dirname, '../../asynchookstests/sampleWithFailureInTestcaseAndAfter.js')\n    ];\n\n    return runTests(testsPath, settings({\n      output_folder: 'output',\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter: function (results) {\n          assert.strictEqual(results.assertions, 2);\n          assert.strictEqual(results.errmessages.length, 1);\n          assert.strictEqual(results.failed, 2);\n          assert.ok(results.lastError instanceof Error);\n          assert.ok(results.lastError.message.startsWith('Failed [strictEqual]:'), results.lastError.message);\n          assert.strictEqual(typeof results.modules.sampleWithFailureInTestcaseAndAfter, 'object');\n          assert.strictEqual(results.modules.sampleWithFailureInTestcaseAndAfter.assertionsCount, 2);\n          assert.strictEqual(results.modules.sampleWithFailureInTestcaseAndAfter.errmessages.length, 1);\n          assert.strictEqual(results.modules.sampleWithFailureInTestcaseAndAfter.failedCount, 2);\n          assert.strictEqual(results.modules.sampleWithFailureInTestcaseAndAfter.skippedAtRuntime.length, 0);\n          assert.strictEqual(results.modules.sampleWithFailureInTestcaseAndAfter.skipped.length, 0);\n          assert.strictEqual(results.modules.sampleWithFailureInTestcaseAndAfter.completed['demo test async'].assertions.length, 1);\n        }\n      },\n      screenshots: {\n        enabled: false\n      }\n    }))\n      .then(_ => {\n        return readFilePromise('output/FIREFOX_TEST_firefox__sampleWithFailureInTestcaseAndAfter.xml');\n      })\n      .then(data => {\n        const content = data.toString();\n        assert.ok(content.includes('<system-err>'), 'Report should contain <system-err>');\n        assert.ok(content.includes('<failure message=\"Failed [equal]: (0 == 1) - expected &#34;1&#34; but got: &#34;0&#34;'), 'Report should contain Failed [equal]: (0 == 1)');\n        assert.ok(content.includes('Failed [strictEqual]: '), 'Report should contain Failed [strictEqual]');\n        assert.ok(content.indexOf('sampleWithFailureInTestcaseAndAfter.js') > -1, 'Report should contain stack trace');\n      });\n  });\n\n  it('testRun with jUnit output and errors in testcase and failure in after hook', function () {\n    const testsPath = [\n      path.join(__dirname, '../../asynchookstests/sampleWithErrorInTestcaseAndAfter.js')\n    ];\n\n    return runTests(testsPath, settings({\n      output_folder: 'output',\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter: function (results) {\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errmessages.length, 2);\n          assert.strictEqual(results.failed, 1);\n          assert.ok(results.lastError instanceof Error);\n          assert.ok(results.lastError.message.startsWith('Failed [strictEqual]:'), results.lastError.message);\n          assert.strictEqual(typeof results.modules.sampleWithErrorInTestcaseAndAfter, 'object');\n          assert.strictEqual(results.modules.sampleWithErrorInTestcaseAndAfter.assertionsCount, 1);\n          assert.strictEqual(results.modules.sampleWithErrorInTestcaseAndAfter.errmessages.length, 2);\n          assert.strictEqual(results.modules.sampleWithErrorInTestcaseAndAfter.failedCount, 1);\n          assert.strictEqual(results.modules.sampleWithErrorInTestcaseAndAfter.skippedAtRuntime.length, 0);\n          assert.strictEqual(results.modules.sampleWithErrorInTestcaseAndAfter.skipped.length, 0);\n          assert.strictEqual(results.modules.sampleWithErrorInTestcaseAndAfter.completed['demo test async'].assertions.length, 0);\n          assert.strictEqual(results.modules.sampleWithErrorInTestcaseAndAfter.completed['demo test async'].errors, 1);\n          assert.ok(results.modules.sampleWithErrorInTestcaseAndAfter.completed['demo test async'].lastError instanceof Error);\n          assert.strictEqual(results.modules.sampleWithErrorInTestcaseAndAfter.completed['demo test async'].lastError.message, 'error in testcase');\n        }\n      },\n      output: false,\n      screenshots: {\n        enabled: false\n      }\n    }))\n      .then(_ => {\n        return readFilePromise('output/FIREFOX_TEST_firefox__sampleWithErrorInTestcaseAndAfter.xml');\n      })\n      .then(data => {\n        const content = data.toString();\n        assert.ok(content.includes('<system-err>'), 'Report should contain <system-err>');\n        assert.ok(content.includes('<error message=\"error in testcase\" type=\"error\">'), 'Report should contain <error>');\n        assert.ok(content.includes('Failed [strictEqual]:'), 'Report should contain Failed [strictEqual]');\n        assert.ok(content.indexOf('sampleWithErrorInTestcaseAndAfter.js') > -1, 'Report should contain stack trace');\n      });\n  });\n\n  it('testRun with jUnit output and failures in before and after hook', function () {\n    const testsPath = [\n      path.join(__dirname, '../../asynchookstests/sampleWithFailureInBeforeAndAfter.js')\n    ];\n\n    return runTests(testsPath, settings({\n      output_folder: 'output',\n      globals: {\n        waitForConditionPollInterval: 20,\n        waitForConditionTimeout: 50,\n        retryAssertionTimeout: 50,\n        reporter: function (results) {\n          assert.strictEqual(results.assertions, 2);\n          assert.strictEqual(results.errmessages.length, 2);\n          assert.strictEqual(results.failed, 2);\n          assert.ok(results.lastError instanceof Error);\n          assert.strictEqual(typeof results.modules.sampleWithFailureInBeforeAndAfter, 'object');\n          assert.strictEqual(results.modules.sampleWithFailureInBeforeAndAfter.assertionsCount, 2);\n          assert.strictEqual(results.modules.sampleWithFailureInBeforeAndAfter.errmessages.length, 2);\n          assert.strictEqual(results.modules.sampleWithFailureInBeforeAndAfter.failedCount, 2);\n          assert.strictEqual(results.modules.sampleWithFailureInBeforeAndAfter.skippedAtRuntime.length, 0);\n          assert.strictEqual(results.modules.sampleWithFailureInBeforeAndAfter.skipped.length, 0);\n        }\n      },\n      screenshots: {\n        enabled: false\n      }\n    }))\n      .then(_ => {\n        return readFilePromise('output/FIREFOX_TEST_firefox__sampleWithFailureInBeforeAndAfter.xml');\n      })\n      .then(data => {\n        const content = data.toString();\n        assert.ok(content.includes('<system-err>'), 'Report should contain <system-err>');\n        assert.ok(content.includes('Failed [equal]: (0 == 1)'), 'Report should contain Failed [equal]: (0 == 1)');\n        assert.ok(content.includes('Failed [strictEqual]'), 'Report should contain Failed [strictEqual]');\n        assert.ok(content.includes('sampleWithFailureInBeforeAndAfter.js'), 'Report should contain stack trace');\n      });\n  });\n\n  it('testRunWithJUnitOutput', function() {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withsubfolders')\n    ];\n\n    return runTests(testsPath, settings({\n      output_folder: 'output',\n      silent: true,\n      globals: {reporter: function() {}}\n    }))\n      .then(_ => {\n        return readDirPromise(testsPath[0]);\n      })\n      .then(list => {\n        const simpleReportFile = 'output/simple/FIREFOX_TEST_firefox__sample.xml';\n        const tagsReportFile = 'output/tags/FIREFOX_TEST_firefox__sampleTags.xml';\n\n        assert.deepStrictEqual(list, ['simple', 'tags'], 'The subfolders have not been created.');\n        assert.ok(fileExistsSync(simpleReportFile), 'The simple report file was not created.');\n        assert.ok(fileExistsSync(tagsReportFile), 'The tags report file was not created.');\n\n        return readFilePromise(simpleReportFile);\n      })\n      .then(data => {\n        const content = data.toString();\n        assert.ok(/<testsuite[\\s]+name=\"simple\\.sample\"[\\s]+id=\"simple\\.sample\"[\\s]+errors=\"0\"[\\s]+failures=\"0\"[\\s]+hostname=\"\"[\\s]+package=\"simple\"[\\s]+skipped=\"0\"[\\s]+tests=\"1\"/.test(content),\n          'Report does not contain correct testsuite information.');\n\n        assert.ok(/<testcase[\\s]+name=\"simpleDemoTest\"[\\s]+classname=\"simple\\.sample\"[\\s]+time=\"[.\\d]+\"[\\s]+assertions=\"1\">/.test(content),\n          'Report does not contain the correct testcase element.');\n      });\n  });\n\n  it('testRun with jUnit output and describe', function() {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withdescribe/basic')\n    ];\n\n    return runTests(testsPath, settings({\n      src_folders: ['test/sampletests/withdescribe'],\n      output_folder: 'output',\n      silent: true,\n      globals: {reporter: function() {}}\n    }))\n      .then(_ => {\n        const basicReportFile = 'output/basic/FIREFOX_TEST_firefox__sample.xml';\n\n        assert.ok(fileExistsSync(basicReportFile), 'The basic report file was not created.');\n\n        return readFilePromise(basicReportFile);\n      })\n      .then(data => {\n        const content = data.toString();\n        assert.match(content, /<testsuite[\\s]+name=\"basic describe test\"[\\s]+id=\"basic.sample\"[\\s]+/,\n          'Report does not contain correct testsuite name.');\n\n        assert.match(content, /<testcase[\\s]+name=\"demoTest\"[\\s]+classname=\"basic describe test\"/,\n          'Report does not contain the correct testcase classname.');\n      });\n  });\n});\n\n// util to replace deprecated fs.existsSync\nfunction fileExistsSync(path) {\n  try {\n    fs.statSync(path);\n\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n"
  },
  {
    "path": "test/src/runner/testRunnerMixedFiles.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunnerMixedFiles', function() {\n  /** @type {import(\"ts-node\").Service} */\n  let tsNode;\n\n  before(function(done) {\n    tsNode = require('ts-node').register({\n      project: path.resolve('test/tsconfig.json'),\n      swc: true\n    });\n\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    tsNode.enabled(false);\n\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  this.timeout(5000);\n\n  it('testRunWithoutDisablingTypescriptExplicitly', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/mixed-files');\n    const globals = {\n      reporter({lastError, errmessages, modules}) {\n        if (lastError) {\n          throw lastError;\n        }\n  \n        if (errmessages.length) {\n          throw new Error(errmessages[0]);\n        }\n\n        assert.ok('sampleJs' in modules);\n        assert.ok('sampleTs' in modules);\n        assert.strictEqual(modules['sampleJs'].modulePath, path.join(__dirname, '../../sampletests/mixed-files/sampleJs.js'));\n        assert.strictEqual(modules['sampleTs'].modulePath, path.join(__dirname, '../../sampletests/mixed-files/sampleTs.ts'));\n      }\n    };\n\n    return runTests(testsPath, settings({\n      custom_commands_path: path.join(__dirname, '../../extra/commands'),\n      globals,\n      output: false,\n      disable_typescript: false\n    }));\n  });\n\n  it('testRunWithoutDisablingTypescriptImplicitly', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/mixed-files');\n    const globals = {\n      reporter({lastError, errmessages, modules}) {\n        if (lastError) {\n          throw lastError;\n        }\n  \n        if (errmessages.length) {\n          throw new Error(errmessages[0]);\n        }\n  \n        assert.ok('sampleJs' in modules);\n        assert.ok('sampleTs' in modules);\n        assert.strictEqual(modules['sampleJs'].modulePath, path.join(__dirname, '../../sampletests/mixed-files/sampleJs.js'));\n        assert.strictEqual(modules['sampleTs'].modulePath, path.join(__dirname, '../../sampletests/mixed-files/sampleTs.ts'));\n      }\n    };\n\n    return runTests(testsPath, settings({\n      custom_commands_path: path.join(__dirname, '../../extra/commands'),\n      globals\n    }));\n  });\n\n  it('testRunSimpleDisablingTypescript', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/mixed-files');\n    const globals = {\n      reporter({lastError, errmessages, modules}) {\n        if (lastError) {\n          throw lastError;\n        }\n\n        if (errmessages.length) {\n          throw new Error(errmessages[0]);\n        }\n\n        assert.ok('sampleJs' in modules);\n        assert.strictEqual(typeof(modules['sampleTs']), 'undefined');\n        assert.strictEqual(modules['sampleJs'].modulePath, path.join(__dirname, '../../sampletests/mixed-files/sampleJs.js'));\n      }\n    };\n\n    return runTests(testsPath, settings({\n      custom_commands_path: path.join(__dirname, '../../extra/commands'),\n      globals,\n      disable_typescript: true\n    }));\n  }); \n});\n"
  },
  {
    "path": "test/src/runner/testRunnerRerunJsonOutput.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst rimraf = require('rimraf');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\nconst {mkpath} = common.require('utils');\n\ndescribe('testRunnerRerunJsonOutput', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => done());\n  });\n\n  beforeEach(function(done) {\n    mkpath('output', function(err) {\n      if (err) {\n        return done(err);\n      }\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    rimraf('output', done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  it('testRunWithRerunJsonOutput', function() {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withsubfolders')\n    ];\n\n    return runTests({source: testsPath, reporter: 'minimalJson'}, settings({\n      output_folder: 'output',\n      silent: true,\n      globals: {reporter: function() {}}\n    }))\n      .then(_ => {\n        return readDirPromise(testsPath[0]);\n      })\n      .then(list => {\n        const rerunJsonReportFile = path.resolve('output/minimal_report.json');\n        assert.ok(fileExistsSync(rerunJsonReportFile), 'The simple report file was not created.');\n\n        return require(rerunJsonReportFile);\n      })\n      .then(data => {\n        assert.strictEqual(typeof data.modules, 'object');\n        Object.keys(data.modules).forEach((moduleKey) => {\n          const module = data.modules[moduleKey];\n      \n          assert.ok(Object.keys(module).includes('modulePath'));\n          assert.ok(Object.keys(module).includes('status'));\n        });\n      });\n  });\n});\n\nfunction readDirPromise(dirName) {\n  return new Promise(function(resolve, reject) {\n    fs.readdir(dirName, function(err, result) {\n      if (err) {\n        return reject(err);\n      }\n\n      resolve(result);\n    });\n  });\n}\n\n// util to replace deprecated fs.existsSync\nfunction fileExistsSync(path) {\n  try {\n    fs.statSync(path);\n\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n"
  },
  {
    "path": "test/src/runner/testRunnerScreenshotsOutput.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst rimraf = require('rimraf');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunnerScreenshotsOutput', function () {\n  this.timeout(10000);\n  const screenshotFilePath = 'screenshots';\n  const moduleName = 'sample';\n\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      rimraf(screenshotFilePath, done);\n    });\n  });\n\n  afterEach(function(done) {\n    rimraf(screenshotFilePath, done);\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, function() {\n      rimraf(screenshotFilePath, done);\n    });\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('takes screenshot on each test failure', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withfailures')\n    ];\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'c2NyZWVuZGF0YQ=='\n      })\n    }, true);\n\n    return runTests(testsPath, settings({\n      skip_testcases_on_fail: false,\n      globals: {\n        waitForConditionPollInterval: 5,\n        waitForConditionTimeout: 5,\n        retryAssertionTimeout: 1,\n        reporter: function () {\n        }\n      },\n      screenshots: {\n        enabled: true,\n        on_failure: true,\n        on_error: true,\n        path: screenshotFilePath\n      }\n    }))\n      .then(_ => {\n        return readDirPromise(`${screenshotFilePath}/${moduleName}`);\n      })\n      .then(files => {\n        assert.ok(Array.isArray(files));\n        assert.strictEqual(files.length, 1);\n        files.forEach((val) => assert.ok(val.endsWith('.png')));\n      });\n  });\n\n  it('takes screenshot for failed test and exits if skip_testcases_on_fail is set to true', function () {\n\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withfailures')\n    ];\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'c2NyZWVuZGF0YQ=='\n      })\n    }, true);\n\n\n    return runTests(testsPath, settings({\n      skip_testcases_on_fail: true,\n      output_folder: 'output',\n      output: false,\n      globals: {\n        waitForConditionPollInterval: 5,\n        waitForConditionTimeout: 5,\n        retryAssertionTimeout: 1,\n        reporter: function () {\n        }\n      },\n      screenshots: {\n        enabled: true,\n        on_failure: true,\n        on_error: true,\n        path: screenshotFilePath\n      }\n    }))\n      .then(_ => {\n        return readDirPromise(`${screenshotFilePath}/${moduleName}`)\n          .then(files => {\n            assert.ok(Array.isArray(files));\n            assert.strictEqual(files.length, 1);\n            files.forEach((val) => assert.ok(val.endsWith('.png')));\n          });\n      });\n  });\n\n  it('doesnt save file if screenshot call is failed', function () {\n\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withfailures')\n    ];\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        status: -1,\n        state: '',\n        code: '',\n        value: null,\n        errorStatus: '',\n        error: 'Unknown command 404 Not Found',\n        httpStatusCode: 404\n      })\n    }, true);\n\n\n    return runTests(testsPath, settings({\n      skip_testcases_on_fail: true,\n      output_folder: 'output',\n      globals: {\n        waitForConditionPollInterval: 5,\n        waitForConditionTimeout: 5,\n        retryAssertionTimeout: 1,\n        reporter: function () {\n        }\n      },\n      screenshots: {\n        enabled: true,\n        on_failure: true,\n        on_error: true,\n        path: screenshotFilePath\n      }\n    }))\n      .then(_ => {\n        return readDirPromise(`${screenshotFilePath}/${moduleName}`)\n          .catch(err => {\n            assert.ok(err instanceof Error);\n            assert.ok(err.message.includes('no such file or directory'));\n          });\n      });\n  });\n\n  it('does not take screenshot if screenshot is disabled', function () {\n\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withfailures')\n    ];\n\n    return runTests(testsPath, settings({\n      skip_testcases_on_fail: true,\n      output_folder: 'output',\n      globals: {\n        waitForConditionPollInterval: 5,\n        waitForConditionTimeout: 5,\n        retryAssertionTimeout: 1,\n        reporter: function () {\n        }\n      },\n      screenshots: {\n        enabled: false,\n        on_failure: true,\n        on_error: true,\n        path: screenshotFilePath\n      }\n    }))\n      .then(_ => {\n        return readDirPromise(`${screenshotFilePath}/${moduleName}`)\n          .catch((err) => {\n            assert.ok(err instanceof Error);\n            assert.ok(err.message.includes('no such file or directory'));\n          });\n      });\n  });\n\n  it('does not take screenshot if screenshot is enabled but on_failure is set to false', function () {\n\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withfailures')\n    ];\n\n    return runTests(testsPath, settings({\n      skip_testcases_on_fail: true,\n      output_folder: 'output',\n      globals: {\n        waitForConditionPollInterval: 5,\n        waitForConditionTimeout: 5,\n        retryAssertionTimeout: 1,\n        reporter: function () {\n        }\n      },\n      screenshots: {\n        enabled: true,\n        on_failure: false,\n        on_error: true,\n        path: screenshotFilePath\n      }\n    }))\n      .then(_ => {\n        return readDirPromise(`${screenshotFilePath}/${moduleName}`)\n          .catch((err) => {\n            assert.ok(err instanceof Error);\n            assert.ok(err.message.includes('no such file or directory'));\n          });\n      });\n  });\n\n  it('emit screenshot event on test failure', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/withfailures')\n    ];\n\n    let screenshotEventExecuted = false;\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/screenshot',\n      method: 'GET',\n      response: JSON.stringify({\n        sessionId: '1352110219202',\n        status: 0,\n        value: 'c2NyZWVuZGF0YQ=='\n      })\n    }, true);\n\n    return runTests(testsPath, settings({\n      skip_testcases_on_fail: false,\n      globals: {\n        waitForConditionPollInterval: 5,\n        waitForConditionTimeout: 5,\n        retryAssertionTimeout: 1,\n        reporter: function () {\n        },\n        registerEventHandlers: function(eventBroadcaster) {\n          eventBroadcaster.on('ScreenshotCreated', (args) => {\n            assert.deepStrictEqual(Object.keys(args), ['path']);\n            screenshotEventExecuted = true;\n          });\n        }\n      },\n      screenshots: {\n        enabled: true,\n        on_failure: true,\n        on_error: true,\n        path: screenshotFilePath\n      }\n    }))\n      .then(_ => {\n        assert.strictEqual(screenshotEventExecuted, true);\n\n        return readDirPromise(`${screenshotFilePath}/${moduleName}`);\n      })\n      .then(files => {\n        assert.ok(Array.isArray(files));\n        assert.strictEqual(files.length, 1);\n        files.forEach((val) => assert.ok(val.endsWith('.png')));\n      });\n  });\n});\n\nfunction readDirPromise(dirName) {\n  return new Promise(function(resolve, reject) {\n    fs.readdir(dirName, function(err, result) {\n      if (err) {\n        return reject(err);\n      }\n\n      resolve(result);\n    });\n  });\n}\n\n\n"
  },
  {
    "path": "test/src/runner/testRunnerSessionCreate.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunnerSessionCreate', function () {\n  before(function (done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function (done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function () {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('testRunner with session create error using webdriver', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/simple'),\n      path.join(__dirname, '../../sampletests/async')\n    ];\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 500,\n      postdata: JSON.stringify({\n        capabilities: {firstMatch: [{}], alwaysMatch: {\n          browserName: 'firefox',\n          'nightwatch:options': {name: 'test-Name'},\n          'moz:firefoxOptions': {prefs: {'remote.active-protocols': 3}}\n        }}\n      }),\n      response: JSON.stringify({\n        value: {\n          error: 'session not created',\n          message: 'Session is already started'\n        }\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 500,\n      postdata: JSON.stringify({\n        capabilities: {firstMatch: [{}], alwaysMatch: {\n          browserName: 'firefox',\n          'nightwatch:options': {name: 'test-Name'},\n          'moz:firefoxOptions': {prefs: {'remote.active-protocols': 3}}\n        }}\n      }),\n      response: JSON.stringify({\n        value: {\n          error: 'session not created',\n          message: 'Session is already started'\n        }\n      })\n    }, true);\n\n    const globals = {\n      reporter(results) {\n        const sep = path.sep;\n        assert.strictEqual(results.errors, 2);\n        assert.strictEqual(Object.keys(results.modules).length, 2);\n        assert.ok(Object.keys(results.modules).includes(`async${sep}test${sep}sample`));\n        assert.ok(Object.keys(results.modules).includes(`simple${sep}test${sep}sample`));\n        assert.ok(results.lastError instanceof Error);\n\n        assert.strictEqual(results.lastError.message, 'An error occurred while creating a new GeckoDriver session: [SessionNotCreatedError] Session is already started');\n      }\n    };\n\n    return runTests({'reuse-browser': true, source: testsPath}, settings({\n      desiredCapabilities: {\n        'nightwatch:options': {\n          name: 'test-Name'\n        }\n      },\n      selenium_host: null,\n      webdriver: {\n        host: 'localhost',\n        timeout_options: {\n          retry_attempts: 0\n        }\n      },\n      globals,\n      output: false,\n      output_folder: false\n    }));\n  });\n\n  it('testRunner with session create error using webdriver with --fail-fast argv', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/simple'),\n      path.join(__dirname, '../../sampletests/async')\n    ];\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 500,\n      postdata: JSON.stringify({\n        capabilities: {firstMatch: [{}], alwaysMatch: {\n          browserName: 'firefox',\n          'nightwatch:options': {name: 'test-Name'},\n          'moz:firefoxOptions': {prefs: {'remote.active-protocols': 3}}\n        }}\n      }),\n      response: JSON.stringify({\n        value: {\n          error: 'session not created',\n          message: 'Session is already started'\n        }\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 500,\n      postdata: JSON.stringify({\n        capabilities: {firstMatch: [{}], alwaysMatch: {\n          browserName: 'firefox',\n          'nightwatch:options': {name: 'test-Name'},\n          'moz:firefoxOptions': {prefs: {'remote.active-protocols': 3}}\n        }}\n      }),\n      response: JSON.stringify({\n        value: {\n          error: 'session not created',\n          message: 'Session is already started'\n        }\n      })\n    }, true);\n\n    const globals = {\n      reporter(results) {\n        assert.strictEqual(results.errors, 1);\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.lastError.message, 'An error occurred while creating a new GeckoDriver session: [SessionNotCreatedError] Session is already started');\n      }\n    };\n\n    return runTests({\n      source: testsPath,\n      'fail-fast': true\n    }, settings({\n      desiredCapabilities: {\n        'nightwatch:options': {name: 'test-Name'}\n      },\n      selenium_host: null,\n      webdriver: {\n        host: 'localhost',\n        timeout_options: {\n          retry_attempts: 0\n        }\n      },\n      globals,\n      output: false,\n      output_folder: false\n    })).catch(err => {\n      return err;\n    }).then(err => {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.name, 'SessionNotCreatedError');\n    });\n\n  });\n\n  it('testRunner with session create error using webdriver with enable_fail_fast setting', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/simple'),\n      path.join(__dirname, '../../sampletests/async')\n    ];\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 500,\n      postdata: JSON.stringify({\n        capabilities: {firstMatch: [{}], alwaysMatch: {\n          browserName: 'firefox',\n          'nightwatch:options': {name: 'test-Name'},\n          'moz:firefoxOptions': {prefs: {'remote.active-protocols': 3}}\n        }}\n      }),\n      response: JSON.stringify({\n        value: {\n          error: 'session not created',\n          message: 'Session is already started'\n        }\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 500,\n      postdata: JSON.stringify({\n        capabilities: {firstMatch: [{}], alwaysMatch: {\n          browserName: 'firefox',\n          'nightwatch:options': {name: 'test-Name'},\n          'moz:firefoxOptions': {prefs: {'remote.active-protocols': 3}}\n        }}\n      }),\n      response: JSON.stringify({\n        value: {\n          error: 'session not created',\n          message: 'Session is already started'\n        }\n      })\n    }, true);\n\n    const globals = {\n      reporter(results) {\n        assert.strictEqual(results.errors, 1);\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.lastError.message, 'An error occurred while creating a new GeckoDriver session: [SessionNotCreatedError] Session is already started');\n      }\n    };\n\n    return runTests({\n      source: testsPath\n    }, settings({\n      desiredCapabilities: {\n        'nightwatch:options': {name: 'test-Name'}\n      },\n      selenium_host: null,\n      webdriver: {\n        host: 'localhost',\n        timeout_options: {\n          retry_attempts: 0\n        }\n      },\n      globals,\n      output: false,\n      output_folder: false,\n      enable_fail_fast: true\n    })).catch(err => {\n      return err;\n    }).then(err => {\n      assert.ok(err instanceof Error);\n      assert.strictEqual(err.name, 'SessionNotCreatedError');\n    });\n\n  });\n\n  it('testRunner with session ECONNREFUSED error using webdriver', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/simple'),\n      path.join(__dirname, '../../sampletests/async')\n    ];\n\n    const globals = {\n      reporter(results) {\n        assert.strictEqual(results.errors, 2);\n        assert.strictEqual(results.errmessages.length, 2);\n        assert.strictEqual(Object.keys(results.modules).length, 2);\n\n        assert.strictEqual(results.lastError.sessionCreate, true);\n        assert.ok(results.lastError instanceof Error);\n        assert.strictEqual(results.lastError.code, 'ECONNREFUSED');\n        assert.strictEqual(results.lastError.showTrace, false);\n        assert.match(results.lastError.message, /An error occurred while creating a new GeckoDriver session: Connection refused to .*9999\\. If the Webdriver\\/Selenium service is managed by Nightwatch, check if \"start_process\" is set to \"true\"\\./);\n      }\n    };\n\n    return runTests(testsPath, settings({\n      selenium_host: null,\n      webdriver: {\n        host: 'localhost',\n        port: 9999\n      },\n      output: false,\n      globals\n    })).catch(err => {\n      assert.ok(err instanceof Error);\n      if (err.code === 'ERR_ASSERTION') {\n        throw err;\n      }\n      assert.strictEqual(err.code, 'ECONNREFUSED');\n      assert.strictEqual(err.sessionCreate, true);\n      assert.strictEqual(err.sessionConnectionRefused, true);\n    });\n  });\n\n  it('testRunner with not found server_path error', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/simple')\n    ];\n\n    const globals = {\n      reporter(results) {\n        assert.strictEqual(results.errors, 1);\n        assert.strictEqual(results.errmessages.length, 1);\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n\n        assert.strictEqual(results.lastError.sessionCreate, true);\n        assert.strictEqual(results.lastError.showTrace, false);\n        assert.ok(results.lastError instanceof Error);\n        assert.ok(results.lastError.detailedErr.includes(' Verify if GeckoDriver is configured correctly; using:'));\n        assert.strictEqual(results.lastError.message, 'An error occurred while creating a new GeckoDriver session: [Error] spawn /bin/xxxxx ENOENT');\n      }\n    };\n\n    return runTests(testsPath, settings({\n      selenium_host: null,\n      webdriver: {\n        start_process: true,\n        server_path: '/bin/xxxxx',\n        host: 'localhost',\n        port: 4444\n      },\n      globals\n    })).catch(err => {\n      assert.ok(err instanceof Error);\n      if (err.code === 'ERR_ASSERTION') {\n        throw err;\n      }\n      assert.strictEqual(err.code, 'ECONNREFUSED');\n      assert.strictEqual(err.sessionCreate, true);\n      assert.strictEqual(err.sessionConnectionRefused, true);\n    });\n  });\n\n  it('testRunner with incorrect server_path error', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/simple')\n    ];\n\n    const globals = {\n      reporter(results) {\n        assert.strictEqual(results.errors, 1);\n        assert.strictEqual(results.errmessages.length, 1);\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n\n        assert.strictEqual(results.lastError.sessionCreate, true);\n        assert.strictEqual(results.lastError.showTrace, false);\n        assert.ok(results.lastError instanceof Error);\n        assert.ok(results.lastError.detailedErr.startsWith(' Verify if GeckoDriver is configured correctly; using:'));\n        assert.strictEqual(results.lastError.message, 'An error occurred while creating a new GeckoDriver session: [Error] Server terminated early with status 9');\n      }\n    };\n\n    return runTests(testsPath, settings({\n      selenium_host: null,\n      webdriver: {\n        start_process: true,\n        server_path: process.argv[0],\n        host: 'localhost',\n        port: 4444\n      },\n      globals\n    })).catch(err => {\n      assert.ok(err instanceof Error);\n      if (err.code === 'ERR_ASSERTION') {\n        throw err;\n      }\n      assert.strictEqual(err.code, 'ECONNREFUSED');\n      assert.strictEqual(err.sessionCreate, true);\n      assert.strictEqual(err.sessionConnectionRefused, true);\n    });\n  });\n\n  it('test runner with reusing browser sessions', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/reusebrowser')];\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 200,\n      postdata: JSON.stringify({\n        desiredCapabilities: {browserName: 'firefox', name: 'first-test'},\n        capabilities: {alwaysMatch: {browserName: 'firefox'}}\n      }),\n      response: JSON.stringify({\n        status: 0,\n        sessionId: '1352110219202'\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/1352110219202',\n      method: 'DELETE',\n      statusCode: 200,\n      response: JSON.stringify({\n        status: 0\n      })\n    }, true);\n\n\n\n\n    const globals = {\n      reporter(results) {\n        const sep = path.sep;\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(Object.keys(results.modules).length, 2);\n        assert.ok(Object.keys(results.modules).includes('firstTest'));\n        assert.ok(Object.keys(results.modules).includes('secondTest'));\n      }\n    };\n\n    return runTests({\n      source: testsPath,\n      'reuse-browser': true\n    }, settings({\n      selenium_host: null,\n      webdriver: {\n        host: 'localhost'\n      },\n      globals,\n      output: false,\n      output_folder: false\n    }));\n  });\n\n  it('test runner with reusing browser sessions - using globals', function () {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/reusebrowser')];\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 200,\n      postdata: JSON.stringify({\n        desiredCapabilities: {browserName: 'firefox', name: 'first-test'},\n        capabilities: {alwaysMatch: {browserName: 'firefox'}}\n      }),\n      response: JSON.stringify({\n        status: 0,\n        sessionId: '1352110219202'\n      })\n    }, true);\n\n    MockServer.addMock({\n      url: '/session/1352110219202',\n      method: 'DELETE',\n      statusCode: 200,\n      response: JSON.stringify({\n        status: 0\n      })\n    }, true);\n\n\n\n\n    const globals = {\n      reuseBrowserSession: true,\n      reporter(results) {\n        const sep = path.sep;\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(Object.keys(results.modules).length, 2);\n        assert.ok(Object.keys(results.modules).includes('firstTest'));\n        assert.ok(Object.keys(results.modules).includes('secondTest'));\n      }\n    };\n\n    return runTests({\n      source: testsPath\n    }, settings({\n      selenium_host: null,\n      webdriver: {\n        host: 'localhost'\n      },\n      globals,\n      output: false,\n      output_folder: false\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerTypeScript.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunnerTypeScript', function() {\n  /** @type {import(\"ts-node\").Service} */\n  let tsNode;\n\n  before(function(done) {\n    tsNode = require('ts-node').register({\n      esm: false,\n      // Always compile and execute .ts files as CommonJS,\n      // even in ESM projects.\n      moduleTypes: {\n        '**/*.ts': 'cjs'\n      }\n    });\n\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    tsNode.enabled(false);\n\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  this.timeout(5000);\n\n  it('testRunSimple', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/typescript');\n    const globals = {\n      reporter({lastError, errmessages, modules}) {\n        if (lastError) {\n          throw lastError;\n        }\n\n        if (errmessages.length) {\n          throw new Error(errmessages[0]);\n        }\n\n        assert.ok('sample' in modules);\n        assert.ok('demoTest' in modules['sample'].completed);\n        assert.strictEqual(modules['sample'].modulePath, path.join(__dirname, '../../sampletests/typescript/sample.ts'));\n      }\n    };\n\n    return runTests(testsPath, settings({\n      custom_commands_path: path.join(__dirname, '../../extra/commands'),\n      globals\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerUncaughtErrors.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunWithUncaughtErrors', function() {\n\n  before(function(done) {\n    this.server = MockServer.init();\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('test runner with uncaught exception', function(done) {\n    let testsPath = path.join(__dirname, '../../sampletests/withuncaughterrors');\n    let errorReported = false;\n    let testErr;\n\n    let globals = {\n      reporter(results) {\n        if (results.errmessages.length) {\n          errorReported = true;\n          try {\n            assert.strictEqual(typeof results.modules.demoTestFine, 'object');\n            assert.strictEqual(typeof results.modules.demoTestWithError, 'object');\n            assert.strictEqual(results.passed, 4);\n            assert.strictEqual(results.errors, 1);\n            assert.strictEqual(results.assertions, 4);\n            assert.strictEqual(results.modules.demoTestFine.assertionsCount, 2);\n            assert.strictEqual(results.modules.demoTestFine.passedCount, 2);\n            assert.strictEqual(results.modules.demoTestWithError.assertionsCount, 2);\n            assert.strictEqual(results.modules.demoTestWithError.passedCount, 2);\n            assert.ok(results.errmessages[0].includes('Test Error Uncaught'));\n          } catch (e) {\n            testErr = e;\n          }\n        }\n      }\n    };\n\n\n    const orig = process.exit;\n    process.exit = function(code) {};\n\n    runTests(testsPath, settings({\n      globals\n    }));\n\n    setTimeout(function () {\n      process.exit = orig;\n      try {\n        if (testErr) {\n          done(testErr);\n\n          return;\n        }\n\n        assert.strictEqual(errorReported, true);\n        done();\n      } catch (e) {\n        done(e);\n      }\n    }, 1500);\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerUnitTests.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst Runner = common.require('runner/runner.js');\nconst Settings = common.require('settings/settings.js');\nconst {runTests} = common.require('index.js');\nconst {readFilePromise} = require('../../lib/utils');\n\ndescribe('testRunnerUnitTests', function() {\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('testRunUnitTests', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/unittests');\n\n    return runTests(testsPath, {\n      output_folder: false,\n      unit_tests_mode: true,\n      output: false,\n      globals: {\n        reporter(results) {\n          if (results.lastError) {\n            throw results.lastError;\n          }\n        }\n      }\n    });\n  });\n\n  it('testRunner unit tests with annotation', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/unittests/sampleAnnotation.js');\n\n    const settings = {\n      output_folder: false,\n      output: false,\n      persist_globals: true,\n      globals: {\n        calls: 0,\n        reporter(results) {\n          if (results.lastError) {\n            throw results.lastError;\n          }\n\n          assert.strictEqual(settings.globals.calls, 2);\n        }\n      }\n    };\n\n    return runTests(testsPath, settings);\n  });\n\n  it('testRunner unit tests with annotation and describe', function() {\n    let testsPath = path.join(__dirname, '../../sampletests/withdescribe/unittests/');\n\n    const settings = {\n      output_folder: false,\n      output: false,\n      persist_globals: true,\n      globals: {\n        calls: 0,\n        reporter(results) {\n          if (results.lastError) {\n            throw results.lastError;\n          }\n\n          assert.strictEqual(settings.globals.calls, 2);\n        }\n      }\n    };\n\n    return runTests(testsPath, settings);\n  });\n\n  it('testRunner unit tests with annotation and error thrown', function() {\n    let testsPath = path.join(__dirname, '../../asynchookstests/unittest-error.js');\n\n    const settings = {\n      output_folder: false,\n      output: false,\n      globals: {\n        reporter(results) {\n          assert.ok(results.lastError instanceof Error);\n          assert.ok(results.lastError.message.includes('There is already a .client property defined in'));\n        }\n      }\n    };\n\n    return runTests(testsPath, settings);\n  });\n\n  it('test run unit tests with junit output and failures', function() {\n    let testsPath = [\n      path.join(__dirname, '../../asynchookstests/unittest-failure')\n    ];\n\n    return runTests(testsPath, {\n      output_folder: 'output',\n      unit_tests_mode: true,\n      output: false,\n      globals: {\n        reporter(results) {\n          assert.strictEqual(results.passed, 0);\n          assert.strictEqual(results.failed, 1);\n          assert.strictEqual(results.errors, 0);\n          assert.strictEqual(results.assertions, 1);\n          assert.strictEqual(results.errmessages.length, 0);\n          assert.ok(results.lastError instanceof Error);\n          assert.strictEqual(results.lastError.name, 'AssertionError');\n          assert.ok(results.modules['unittest-failure'].lastError instanceof Error);\n          assert.strictEqual(results.modules['unittest-failure'].lastError.name, 'AssertionError');\n          assert.strictEqual(results.modules['unittest-failure'].assertionsCount, 1);\n          assert.strictEqual(results.modules['unittest-failure'].testsCount, 1);\n          assert.strictEqual(results.modules['unittest-failure'].failedCount, 1);\n          assert.strictEqual(results.modules['unittest-failure'].errorsCount, 0);\n          assert.strictEqual(results.modules['unittest-failure'].passedCount, 0);\n          assert.strictEqual(results.modules['unittest-failure'].completed.demoTest.assertions.length, 1);\n\n          const {completed} = results.modules['unittest-failure'];\n          const {assertions} = completed.demoTest;\n          assert.strictEqual(completed.demoTest.failed, 1);\n          assert.ok(completed.demoTest.stackTrace.startsWith('AssertionError [ERR_ASSERTION]: Expected values to be strictly equal'));\n          assert.strictEqual(assertions[0].failure, 'expected \"0\" but got: \"1\"');\n          assert.strictEqual(assertions[0].fullMsg, 'Expected values to be strictly equal:\\n\\n1 !== 0\\n - expected \"0\" but got: \"1\"');\n          assert.strictEqual(assertions[0].message, 'Expected values to be strictly equal:\\n\\n1 !== 0\\n - expected \"0\" but got: \"1\"');\n          assert.ok(assertions[0].stackTrace.startsWith, 'AssertionError [ERR_ASSERTION]: 1 == 0 - expected \"0\" but got: \"1\"');\n        }\n      }\n    })\n      .then(runner => {\n        let sampleReportFile = 'output/unittest-failure.xml';\n        assert.ok(fileExistsSync(sampleReportFile), 'The sample file report was not created.');\n\n        return readFilePromise(sampleReportFile);\n      })\n      .then(data => {\n        let content = data.toString();\n        assert.ok(content.includes('<failure message=\"Expected values to be strictly equal:\\n\\n1 !== 0\\n - expected &#34;0&#34; but got: &#34;1&#34;\">AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:'), 'Report does not contain failure information.');\n      });\n  });\n\n  it('test async unit test with timeout error', function() {\n    let testsPath = path.join(__dirname, '../../asynchookstests/unittest-async-timeout.js');\n\n    let settings = Settings.parse({\n      output_folder: 'output',\n      unit_tests_mode: true,\n      persist_globals: true,\n      output: false,\n      globals: {\n        calls: 0,\n        unitTestsTimeout: 10,\n        reporter() {}\n      }\n    });\n\n    let runner = Runner.create(settings, {\n      reporter: 'junit'\n    });\n\n    return Runner.readTestSource(settings, {\n      _source: [testsPath]\n    })\n      .then(modules => {\n        return runner.run(modules);\n      })\n      .then(hasFailed => {\n        assert.ok(hasFailed);\n\n        let err = runner.results.lastError;\n        assert.ok(err instanceof Error);\n        assert.ok(fileExistsSync('output/unittest-async-timeout.xml'));\n        assert.strictEqual(err.name, 'TimeoutError');\n        assert.strictEqual(err.message, 'done() callback timeout of 10ms was reached while executing \"demoTest\". ' +\n        'Make sure to call the done() callback when the operation finishes.');\n      });\n  });\n});\n\n// util to replace deprecated fs.existsSync\nfunction fileExistsSync(path) {\n  try {\n    fs.statSync(path);\n\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n"
  },
  {
    "path": "test/src/runner/testRunnerUsingWithin.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunner using within', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('test Runner with within', function() {\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/elements',\n      postdata: '{\"using\":\"css selector\",\"value\":\"#finlandia\"}',\n      response: JSON.stringify({sessionId: '1352110219202', status: 0, value: [{ELEMENT: '10'}]})\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/execute/sync',\n      statusCode: 200,\n      method: 'POST',\n      response: JSON.stringify({sessionId: '1352110219202', status: 0, value: true})\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/0/elements',\n      response: JSON.stringify({sessionId: '1352110219202', status: 0, value: [{ELEMENT: '10'}]})\n    });\n\n    MockServer.addMock({\n      url: '/wd/hub/session/1352110219202/element/10/click',\n      response: JSON.stringify({sessionId: '1352110219202', status: 0, value: null})\n    });\n\n    const testsPath = path.join(__dirname, '../../sampletests/usingwithin');\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n\n        assert.strictEqual(results.passed, 3);\n        assert.strictEqual(results.failed, 0);\n        assert.strictEqual(results.errors, 0);\n      }\n    };\n\n    return runTests(testsPath, settings({\n      output: false,\n      custom_commands_path: [path.join(__dirname, '../../extra/commands')],\n      globals\n    }));\n  });\n\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerWithAsyncAssertionFailure.js",
    "content": "const common = require('../../common.js');\nconst path = require('path');\nconst assert = require('assert');\nconst Globals = require('../../lib/globals/commands.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('test Runner with async and assertion failure', function() {\n  const originalExit = process.exit;\n  this.timeout(15000);\n\n  beforeEach(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  afterEach(function(done) {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.exit = originalExit;\n    Globals.afterEach.call(this, done);\n  });\n\n  it('test run mocha samples with async and assertion failures', function() {\n    const globals = {\n      test_calls: 0,\n      retryAssertionTimeout: 0,\n      reporter(results) {\n        assert.strictEqual(globals.test_calls, 16);\n      }\n    };\n\n    return runTests(path.join(__dirname, '../../sampletests/asyncwithfailures/'), settings({\n      globals,\n      skip_testcases_on_fail: false,\n      output: false,\n      silent: false\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerWithPageObjects.js",
    "content": "const path = require('path');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst MockServer = require('../../lib/mockserver.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunner with page objects', function() {\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  after(function(done) {\n    CommandGlobals.afterEach.call(this, done);\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('test Runner with useXpath and PO element selectors', function() {\n    const testsPath = path.join(__dirname, '../../sampletests/withpageobjects');\n    const globals = {\n      waitForConditionPollInterval: 50,\n\n      reporter(results) {\n        if (results.lastError) {\n          throw results.lastError;\n        }\n\n        assert.strictEqual(results.passed, 1);\n        assert.strictEqual(results.failed, 0);\n        assert.strictEqual(results.errors, 0);\n      }\n    };\n\n    return runTests(testsPath, settings({\n      page_objects_path: [path.join(__dirname, '../../extra/pageobjects/pages')],\n      output: false,\n      globals\n    }));\n  });\n\n\n});\n"
  },
  {
    "path": "test/src/runner/testRunnerWithTrace.js",
    "content": "const path = require('path');\nconst fs = require('fs');\nconst assert = require('assert');\nconst common = require('../../common.js');\nconst CommandGlobals = require('../../lib/globals/commands.js');\nconst nocks = require('../../lib/nocks');\nconst rimraf = require('rimraf');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('testRunnerWithTrace', function () {\n  const snapshotFilePath = 'snapshots';\n  const moduleName = 'sample';\n\n  before(function(done) {\n    nocks.enable().cleanAll();\n    CommandGlobals.beforeEach.call(this,  function() {\n      rimraf(snapshotFilePath, done);\n    });\n  });\n\n  afterEach(function(done) {\n    rimraf(snapshotFilePath, done);\n  });\n\n  after(function(done) {\n    nocks.disable();\n    CommandGlobals.afterEach.call(this, function() {\n      rimraf(snapshotFilePath, done);\n    });\n  });\n\n  beforeEach(function() {\n    process.removeAllListeners('exit');\n    process.removeAllListeners('uncaughtException');\n    process.removeAllListeners('unhandledRejection');\n  });\n\n  it('takes snapshot for each traceable command', function () {\n    this.timeout(5000);\n    let testsPath = [\n      path.join(__dirname, '../../sampletests/trace/sample.js')\n    ];\n    const pageHtml = '<!doctype html><html class=\"no-js\" lang=\"\"><head> <meta charset=\"utf-8\"> <title></title> <meta name=\"description\" content=\"\"> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <meta property=\"og:title\" content=\"\"> <meta property=\"og:type\" content=\"\"> <meta property=\"og:url\" content=\"\"> <meta property=\"og:image\" content=\"\"> <link rel=\"manifest\" href=\"site.webmanifest\"> <link rel=\"apple-touch-icon\" href=\"icon.png\"> <link rel=\"stylesheet\" href=\"css/normalize.css\"> <link rel=\"stylesheet\" href=\"css/main.css\"> <meta name=\"theme-color\" content=\"#fafafa\"></head><body> <p>Hello world! This is HTML5 Boilerplate.</p><script src=\"js/vendor/modernizr-3.11.2.min.js\"></script> <script src=\"js/plugins.js\"></script> <script src=\"js/main.js\"></script> <script>window.ga=function (){ga.q.push(arguments)}; ga.q=[]; ga.l=+new Date; ga(\\'create\\', \\'UA-XXXXX-Y\\', \\'auto\\'); ga(\\'set\\', \\'anonymizeIp\\', true); ga(\\'set\\', \\'transport\\', \\'beacon\\'); ga(\\'send\\', \\'pageview\\') </script> <script src=\"https://www.google-analytics.com/analytics.js\" async></script></body></html>';\n    const pageUrl = 'https://nightwatchjs.org';\n\n    nocks.createSession()\n      .url()\n      .elementFound()\n      .visible()\n      .getUrl(pageUrl)\n      .getPageSource(pageHtml)\n      .elementFound()\n      .click()\n      .getUrl(pageUrl)\n      .getPageSource(pageHtml)\n      .deleteSession();\n\n    return runTests(testsPath, settings({\n      skip_testcases_on_fail: false,\n      globals: {\n        waitForConditionPollInterval: 5,\n        waitForConditionTimeout: 5,\n        retryAssertionTimeout: 1,\n        reporter: function (results) {\n          const snapshot1 = results.modulesWithEnv.default.sample.completedSections.click_on_web_login.commands[0].domSnapshot;\n          const snapshot2 = results.modulesWithEnv.default.sample.completedSections.click_on_web_login.commands[1].domSnapshot;\n\n          assert.ok(snapshot1.snapshotFilePath.includes(`snapshots${path.sep}sample${path.sep}navigateTo`));\n          assert.strictEqual(snapshot1.snapshotUrl, 'https://nightwatchjs.org');\n\n          assert.ok(snapshot2.snapshotFilePath.includes(`snapshots${path.sep}sample${path.sep}click`));\n          assert.strictEqual(snapshot2.snapshotUrl, 'https://nightwatchjs.org');\n        },\n        abortOnAssertionFailure: false\n      },\n      trace: {\n        enabled: true,\n        path: snapshotFilePath\n      }\n    }))\n      .then(_ => {\n        return readDirPromise(`${snapshotFilePath}/${moduleName}`);\n      })\n      .then(files => {\n        assert.ok(Array.isArray(files));\n        assert.strictEqual(files.length, 2);\n        files.forEach((val) => assert.ok(val.endsWith('.html')));\n      });\n  });\n\n  it('error while taking snapshot', function () {\n    let testsPath = [\n      path.join(__dirname, '../../sampletests/trace/sample.js')\n    ];\n\n    const pageUrl = 'https://nightwatchjs.org';\n\n    nocks.createSession()\n      .url()\n      .elementFound()\n      .visible()\n      .getUrl(pageUrl)\n      .elementFound()\n      .click()\n      .getUrl(pageUrl)\n      .deleteSession();\n\n    return runTests(testsPath, settings({\n      skip_testcases_on_fail: false,\n      globals: {\n        waitForConditionPollInterval: 5,\n        waitForConditionTimeout: 5,\n        retryAssertionTimeout: 1,\n        reporter: function (results) {\n          assert.ok(results);\n\n          const snapshot1 = results.modulesWithEnv.default.sample.completedSections.click_on_web_login.commands[0].domSnapshot;\n          const snapshot2 = results.modulesWithEnv.default.sample.completedSections.click_on_web_login.commands[1].domSnapshot;\n\n          assert.equal(snapshot1.error, 'failed to fetch pageSource');\n          assert.strictEqual(snapshot2.error, 'failed to fetch pageSource');\n        },\n        abortOnAssertionFailure: false\n      },\n      trace: {\n        enabled: true,\n        path: snapshotFilePath\n      }\n    }))\n      .then(_ => {\n        return readDirPromise(`${snapshotFilePath}/${moduleName}`);\n      })\n      .then(_ => {\n        assert.fail();\n      })\n      .catch(err => {\n        assert.ok(err);\n        assert.strictEqual(err.code, 'ENOENT');\n      });\n  });\n});\n\nfunction readDirPromise(dirName) {\n  return new Promise(function(resolve, reject) {\n    fs.readdir(dirName, function(err, result) {\n      if (err) {\n        return reject(err);\n      }\n\n      resolve(result);\n    });\n  });\n}"
  },
  {
    "path": "test/src/runner/testTagsMatcher.js",
    "content": "const expect = require('@nightwatch/chai').expect;\nconst path = require('path');\nconst common = require('../../common.js');\nconst TagsMatcher = common.require('runner/matchers/tags.js');\n\ndescribe('test TagsMatcher', function() {\n  describe('reading module tags and skiptags from settings', function() {\n    const testCases = [\n      ['undefined', undefined, []],\n      ['null', null, []],\n      ['number', 777, ['777']],\n      ['number array', [777, 888], ['777', '888']],\n      ['empty string', '', []],\n      ['string with one tag', 'a', ['a']],\n      ['string with multiple tags', 'A,b,C,777', ['a', 'b', 'c', '777']],\n      ['empty array', [], []],\n      ['array with one tag', ['a'], ['a']],\n      ['array with multiple tags', ['a', 'B', 'c', 777], ['a', 'b', 'c', '777']]\n    ];\n\n    testCases.forEach(([description, given, expected]) => {\n      it(`${description}`, function() {\n        const result = TagsMatcher.convertTags(given);\n        expect(result).to.deep.equal(expected);\n      });\n    });\n  });\n\n  describe('reading filter tags from settings', function () {\n    const testCases = [\n      ['undefined', undefined, []],\n      ['null', null, []],\n      ['empty string', '', []],\n      ['empty array', [], []],\n      ['number', 777, [['777']]],\n      ['number array: --tag 777 --tag 888', [777, 888], [['777'], ['888']]],\n      ['string with one tag: --tag a', 'a', [['a']]],\n      ['AND tags: --tag A,b,C,777', 'A,b,C,777', [['a', 'b', 'c', '777']]],\n      ['OR tags: --tag A --tag b --tag C --tag 777', ['A', 'b', 'C', '777'], [['a'], ['b'], ['c'], ['777']]],\n      ['AND and OR tags: --tag A,b --tag c,D --tag e,777', ['A,b', 'c,D', 'e,777'], [['a', 'b'], ['c', 'd'], ['e', '777']]]\n    ];\n\n    testCases.forEach(([description, given, expected]) => {\n      it(`${description}`, function () {\n        const result = TagsMatcher.convertFilterTags(given);\n        expect(result).to.deep.equal(expected);\n      });\n    });\n  });\n\n  describe('matching', function () {\n    const testCases = [\n      [\n        'matching tags',\n        ['home', 'login', 'sign-up'],\n        ['home', 'siberia'],\n        undefined,\n        true\n      ],\n      [\n        'matching single filter tag',\n        ['home', 'login', 'sign-up'],\n        ['home'],\n        undefined,\n        true\n      ],\n      [\n        'multiple filter tags as AND match',\n        ['home', 'login', 'siberia', 'sign-up'],\n        ['home,siberia'],\n        undefined,\n        true\n      ],\n      [\n        'multiple filter tags as AND do not match',\n        ['home', 'login', 'sign-up'],\n        ['home,siberia'],\n        undefined,\n        false\n      ],\n      [\n        'non-matching tags',\n        ['boroboro', 'siberia'],\n        ['home', 'login', 'sign-up'],\n        undefined,\n        false\n      ],\n      [\n        'undefined module tags',\n        undefined,\n        ['home', 'login', 'sign-up'],\n        undefined,\n        false\n      ],\n      [\n        'numeric tags',\n        ['101'],\n        ['room', 101],\n        undefined,\n        true\n      ],\n      [\n        'numeric tags single',\n        ['101'],\n        101,\n        undefined,\n        true\n      ],\n      [\n        'skiptag not matching',\n        ['room', 101],\n        undefined,\n        ['101'],\n        false\n      ],\n      [\n        'skiptag matching',\n        ['room', 101],\n        undefined,\n        ['other'],\n        true\n      ],\n      [\n        'skiptag matching - undefined local tags',\n        undefined,\n        undefined,\n        ['other'],\n        true\n      ],\n      [\n        'tag filter does not find module, but skiptag does and excludes it',\n        ['room', 101],\n        ['other'],\n        ['101'],\n        false\n      ],\n      [\n        'tag filter does not find module, and skiptag does not and excludes it',\n        ['room', 101],\n        ['other'],\n        ['777'],\n        false\n      ],\n      [\n        'tag filter finds module, skiptag also does and excludes it',\n        ['room', 101],\n        ['room'],\n        ['101'],\n        false\n      ],\n      [\n        'tag filter finds module, and skiptag does not',\n        ['room', 101],\n        ['room'],\n        ['other'],\n        true\n      ]\n    ];\n    testCases.forEach(([description, moduleTags, tag_filter, skiptags, expected]) => {\n      it(`${description}`, function () {\n        const matcher = new TagsMatcher({\n          tag_filter: tag_filter,\n          skiptags: skiptags\n        });\n\n        const context = {\n          getTags() {\n            return moduleTags;\n          }\n        };\n\n        const matched = matcher.checkModuleTags(context);\n\n        expect(matched).to.equal(expected);\n      });\n    });\n  });\n\n  describe('loading and matching', function(){\n    const testCases = [\n      [\n        'module with tags',\n        'sampletests/tags/sample.js',\n        ['home', 'login', 'sign-up'],\n        undefined,\n        true\n      ],\n      [\n        'module with tags single filter tag',\n        'sampletests/tags/sample.js',\n        ['login'],\n        undefined,\n        true\n      ],\n      [\n        'module with tags multiple AND filter tags',\n        'sampletests/tags/sample.js',\n        ['login,other'],\n        undefined,\n        true\n      ],\n      [\n        'loading modules containing an error should not be silent',\n        'extra/mock-errors/sample-error.js',\n        ['home', 'login', 'sign-up'],\n        undefined,\n        false\n      ],\n      [\n        'skiptag test loading module with matching tags',\n        'sampletests/tags/sample.js',\n        undefined,\n        ['login'],\n        false\n      ],\n      [\n        'skiptag test loading module with no tags',\n        'sampletests/simple/test/sample.js',\n        undefined,\n        ['login'],\n        true\n      ]\n    ];\n\n    testCases.forEach(([description, modulePath, tag_filter, skiptags, expected]) => {\n      it(description, async function () {\n        const fullModulePath = path.join(__dirname, '../../' + modulePath);\n\n        const matcher = new TagsMatcher({\n          tag_filter: tag_filter,\n          skiptags: skiptags\n        });\n\n        const matched = await matcher.match(fullModulePath);\n\n        expect(matched).to.equal(expected);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/src/service-builders/testAppiumServer.js",
    "content": "const assert = require('assert');\nconst mockery = require('mockery');\nconst path = require('path');\nconst common = require('../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst Settings = common.require('settings/settings.js');\n\ndescribe('AppiumServer Transport Tests', function () {\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n  });\n\n  afterEach(function(){\n    mockery.deregisterAll();\n    mockery.disable();\n    mockery.resetCache();\n  });\n\n  const sessionData = {\n    sessionId: '111',\n    getId() {\n      return '1111';\n    },\n    getCapabilities() {\n      return {\n        getPlatform() {\n          return 'MAC';\n        },\n        getBrowserName() {\n          return 'chrome';\n        },\n        getBrowserVersion() {\n          return '11';\n        },\n        get(name) {\n          return name;\n        },\n        keys() {\n          return new Map();\n        }\n      };\n    }\n  };\n\n  const mockDriver = {\n    session_: Promise.resolve(),\n    async getSession() {\n      return sessionData;\n    },\n    async getExecutor() {\n      return {\n        w3c: true\n      };\n    }\n  };\n\n  const fn = function() {};\n  function deleteFromRequireCache(location) {\n    const entry = Object.keys(require.cache).filter(item => {\n      return item.includes(location);\n    });\n\n    entry.forEach(item => {\n      delete require.cache[item];\n    });\n  }\n\n  function mockHttpClient({onServerUrl = fn}) {\n    function httpClient() {\n      return class HttpClient {\n        constructor(serverUrl) {\n          onServerUrl(serverUrl);\n        }\n      };\n    }\n\n    mockery.registerMock('./httpclient.js', httpClient);\n  }\n\n  function mockWebDriver({onSessionOpts = fn}) {\n    const SeleniumWebdriver = require('selenium-webdriver');\n    class MockWebDriver extends SeleniumWebdriver.WebDriver {\n      static createSession(executor, options) {\n        onSessionOpts(options);\n\n        return Promise.resolve(mockDriver);\n      }\n    }\n\n    deleteFromRequireCache('node_modules/selenium-webdriver');\n\n    mockery.registerMock('selenium-webdriver', {\n      ...SeleniumWebdriver,\n      WebDriver: MockWebDriver\n    });\n  }\n\n\n  function mockServiceBuilder({onConstruct = fn, onOpts = fn, onSetPort = fn}) {\n    const remote = require('selenium-webdriver/remote');\n    const {Options, SeleniumServer} = remote;\n\n    deleteFromRequireCache('node_modules/selenium-webdriver/remote');\n\n    class MockDriverService {\n      constructor(command, opts) {\n        onConstruct.call(this, command);\n\n        if (opts.port) {\n          onSetPort(opts.port);\n        }\n\n        onOpts(opts);\n      }\n\n      async start() {\n        return {};\n      }\n    }\n\n    mockery.registerMock('selenium-webdriver/remote', {\n      Options,\n      SeleniumServer,\n      DriverService: MockDriverService\n    });\n  }\n\n  async function AppiumServerTestSetup(useSettings, {argv = {}, onLogFile = fn} = {}) {\n    const BaseService = common.require('transport/selenium-webdriver/service-builders/base-service.js');\n    class MockBaseService extends BaseService {\n      constructor(settings) {\n        super(settings);\n\n        this.setOutputFile('');\n\n        assert.strictEqual(this.serviceName, 'Appium Server');\n        assert.strictEqual(this.outputFile, '_appium-server.log');\n        assert.strictEqual(this.defaultPort, 4723);\n        assert.strictEqual(this.npmPackageName, 'appium');\n        assert.strictEqual(this.serviceDownloadUrl, '');\n        assert.strictEqual(this.downloadMessage, 'install Appium globally with \"npm i -g appium\" command, \\n and set \"selenium.server_path\" config option to \"appium\".');\n      }\n      needsSinkProcess() {\n        return true;\n      }\n      hasSinkSupport() {\n        return true;\n      }\n      async writeLogFile() {\n      }\n      async createSinkProcess() {\n        this.process = {\n          kill: () => {}\n        };\n        const logPath = this.getLogPath();\n        if (!logPath) {\n          return true;\n        }\n\n        const filePath = this.getOutputFilePath();\n        onLogFile(filePath);\n      }\n    }\n\n    deleteFromRequireCache('transport/selenium-webdriver/service-builders/base-service.js');\n    mockery.registerMock('./base-service.js', MockBaseService);\n\n    let command;\n    let serverPort;\n    let serverUrl;\n    let logFilePath;\n    let buildOptions;\n    let sessionOptions;\n\n    mockServiceBuilder({\n      onConstruct(cmd) {\n        command = cmd;\n      },\n\n      onSetPort(p) {\n        serverPort = p;\n      },\n\n      onOpts(o) {\n        buildOptions = o;\n      }\n    });\n\n    mockHttpClient({\n      onServerUrl(url) {\n        serverUrl = url;\n      }\n    });\n\n    mockWebDriver({\n      onSessionOpts(opts) {\n        sessionOptions = opts;\n      }\n    });\n\n    const settings = Settings.parse(useSettings);\n\n    const client = NightwatchClient.client(settings, null, {});\n    const {transport} = client;\n\n    const session = await transport.createSession({argv, moduleKey: 'testModuleKey'});\n\n    return {\n      session,\n      command,\n      serverPort,\n      serverUrl,\n      buildOptions,\n      sessionOptions\n    };\n  }\n\n  it('test create session with Appium', async function() {\n    let logFilePath;\n    const {session, command, serverPort, buildOptions, sessionOptions} = await AppiumServerTestSetup({\n      desiredCapabilities: {\n        browserName: '',\n        platformName: 'ios',\n        'appium:options': {\n          automationName: 'XCUITest',\n          app: 'samples/sample.app'\n        }\n      },\n      selenium: {\n        port: 9999,\n        use_appium: true,\n        start_process: true,\n        // server_path is only set automatically when server is started from cli.js\n        server_path: '/path/to/appium/main.js'\n      }\n    }, {\n      argv: {\n        deviceId: '00008030-00024C2C3453402E'\n      },\n      onLogFile(filePath) {\n        logFilePath = filePath;\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n    assert.strictEqual(command, 'node');\n    assert.strictEqual(serverPort, 9999);\n    assert.strictEqual(buildOptions.port, 9999);\n    assert.strictEqual(buildOptions.path, '/wd/hub');\n    assert.deepStrictEqual(buildOptions.args, ['/path/to/appium/main.js', '--port', 9999]);\n    assert.deepStrictEqual(buildOptions.stdio, ['pipe', undefined, undefined]);\n    assert.strictEqual(sessionOptions.browserName, '');\n    assert.strictEqual(sessionOptions.platformName, 'ios');\n    assert.strictEqual(sessionOptions['appium:automationName'], 'XCUITest');\n    assert.strictEqual(sessionOptions['appium:app'], 'samples/sample.app');\n    assert.strictEqual(sessionOptions['appium:udid'], '00008030-00024C2C3453402E');\n    assert.strictEqual('appium:options' in sessionOptions, false);\n    assert.ok(logFilePath.endsWith('testModuleKey_appium-server.log'));\n  });\n\n  it('test create session with globally installed appium 2 server', async function() {\n    mockery.registerMock('chromedriver', {\n      path: '/path/to/chromedriver'\n    });\n\n    let logFilePath;\n    const {command, serverPort, buildOptions, sessionOptions} = await AppiumServerTestSetup({\n      desiredCapabilities: {\n        browserName: null,\n        'appium:options': {\n          app: './sample.apk',\n          chromedriverExecutable: ''\n        }\n      },\n      selenium: {\n        start_process: true,\n        use_appium: true,\n        server_path: 'appium',\n        cli_args: [\n          '--allow-insecure=chromedriver_autodownload'\n        ],\n        default_path_prefix: ''\n      }\n    }, {\n      argv: {\n        deviceId: 'ZD2222W62Y'\n      },\n      onLogFile(filePath) {\n        logFilePath = filePath;\n      }\n    });\n\n    assert.strictEqual(command, 'appium');\n    assert.strictEqual(serverPort, 4723);\n    assert.strictEqual(buildOptions.path, '');\n    assert.deepStrictEqual(buildOptions.args, ['--allow-insecure=chromedriver_autodownload']);\n    assert.deepStrictEqual(buildOptions.stdio, ['pipe', undefined, undefined]);\n    assert.strictEqual(sessionOptions.browserName, null);\n    assert.strictEqual(sessionOptions['appium:app'], './sample.apk');\n    assert.strictEqual(sessionOptions['appium:chromedriverExecutable'], '/path/to/chromedriver');\n    assert.strictEqual(sessionOptions['appium:udid'], 'ZD2222W62Y');\n    assert.strictEqual('appium:options' in sessionOptions, false);\n    assert.ok(logFilePath.endsWith('testModuleKey_appium-server.log'));\n  });\n\n  it('test create session with appium server -- externally managed', async function() {\n    const {session, command, serverPort, serverUrl, buildOptions, sessionOptions} = await AppiumServerTestSetup({\n      desiredCapabilities: {\n        browserName: 'firefox',\n        platformName: 'android',\n        'appium:automationName': 'UiAutomator2'\n\n      },\n      selenium: {\n        host: 'somewhere',\n        port: '4725',\n        start_process: false,\n        use_appium: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'somewhere', port: '4725'\n    });\n    // service not created\n    assert.ok(!serverPort);\n    assert.ok(!command);\n    assert.ok(!buildOptions);\n    // session assertions\n    assert.strictEqual(serverUrl, 'http://somewhere:4725');\n    // sessionOptions is a FirefoxOptions instance\n    assert.strictEqual(sessionOptions.browserName, undefined);\n    assert.strictEqual(sessionOptions.getBrowserName(), 'firefox');\n    assert.strictEqual(sessionOptions.getPlatform(), 'android');\n    assert.strictEqual(sessionOptions.get('appium:automationName'), 'UiAutomator2');\n    assert.strictEqual(sessionOptions.has('appium:options'), false);\n  });\n});\n"
  },
  {
    "path": "test/src/service-builders/testChromeDriver.js",
    "content": "const assert = require('assert');\nconst mockery = require('mockery');\nconst common = require('../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst Settings = common.require('settings/settings.js');\n\ndescribe('ChromeDriver Transport Tests', function () {\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n\n    const {constants, rmdirSync} = require('fs');\n\n    delete require.cache['fs'];\n\n    mockery.registerMock('fs', {\n      existsSync() {\n        return true;\n      },\n      constants,\n      rmdirSync,\n      readFileSync() {\n        return true;\n      }\n    });\n\n  });\n\n  afterEach(function(){\n    mockery.deregisterAll();\n    mockery.disable();\n    mockery.resetCache();\n  });\n\n  const sessionData = {\n    sessionId: '111',\n    getId() {\n      return '1111';\n    },\n    getCapabilities() {\n      return {\n        getPlatform() {\n          return 'MAC';\n        },\n        getBrowserName() {\n          return 'chrome';\n        },\n        getBrowserVersion() {\n          return '11';\n        },\n        get(name) {\n          return name;\n        },\n        keys() {\n          return new Map();\n        }\n      };\n    }\n  };\n\n  const mockDriver = {\n    session_: Promise.resolve(),\n    async getSession() {\n      return sessionData;\n    },\n    async getExecutor() {\n      return {\n        w3c: true\n      };\n    }\n  };\n\n  const fn = function() {};\n  function deleteFromRequireCache(location) {\n    const entry = Object.keys(require.cache).filter(item => {\n      return item.includes(location);\n    });\n\n    entry.forEach(item => {\n      delete require.cache[item];\n    });\n  }\n\n  function createMockDriverBuilder() {\n    const {Builder} = require('selenium-webdriver');\n    class MockBuilder extends Builder {\n      build() {\n        return Promise.resolve(mockDriver);\n      }\n    }\n\n    return new MockBuilder();\n  }\n\n  function mockServiceBuilder({onConstruct = fn, onAddArguments = fn, onSetPort = fn, onSetHostname = fn, onSetPath = fn}) {\n    const chrome = require('selenium-webdriver/chrome');\n    const {Options, ServiceBuilder} = chrome;\n\n    deleteFromRequireCache('node_modules/selenium-webdriver/chrome');\n\n    class MockServiceBuilder extends ServiceBuilder {\n      constructor(server_path) {\n        super(server_path);\n\n        onConstruct.call(this, server_path);\n      }\n\n      setPort(port) {\n        onSetPort(port);\n      }\n\n      setHostname(h) {\n        onSetHostname(h);\n      }\n\n      setPath(h) {\n        onSetPath(h);\n      }\n\n      addArguments(...args) {\n        onAddArguments(args);\n      }\n\n      build() {\n        return {\n          kill() {\n\n          },\n          async start() {\n            return 'http://localhost';\n          }\n        };\n      }\n    }\n\n    mockery.registerMock('selenium-webdriver/chrome', {\n      Options,\n      ServiceBuilder: MockServiceBuilder\n    });\n  }\n\n  async function ChromeDriverTestSetup(useSettings, argv = {}) {\n    const BaseService = common.require('transport/selenium-webdriver/service-builders/base-service.js');\n    class MockBaseService extends BaseService {\n      constructor(settings) {\n        super(settings);\n\n        this.setOutputFile('');\n\n        assert.strictEqual(this.serviceName, 'ChromeDriver');\n        assert.strictEqual(this.outputFile, '_chromedriver.log');\n        assert.strictEqual(this.requiresDriverBinary, false);\n        assert.strictEqual(this.defaultPort, undefined);\n        assert.strictEqual(this.npmPackageName, 'chromedriver');\n        assert.strictEqual(this.serviceDownloadUrl, 'https://sites.google.com/chromium.org/driver/downloads');\n      }\n\n      needsSinkProcess() {\n        return true;\n      }\n      hasSinkSupport() {\n        return true;\n      }\n      async writeLogFile() {\n      }\n      async createSinkProcess() {\n\n      }\n    }\n\n    deleteFromRequireCache('transport/selenium-webdriver/service-builders/base-service.js');\n    mockery.registerMock('./base-service.js', MockBaseService);\n\n    let serverPath;\n    let serverPort;\n    const buildArgs = [];\n    let logFilePath;\n\n    mockServiceBuilder({\n      onConstruct(server_path) {\n        serverPath = server_path;\n      },\n\n      onAddArguments(args) {\n        buildArgs.push(...args);\n      },\n\n      onSetPort(p) {\n        serverPort = p;\n      }\n    });\n\n    const settings = Settings.parse(useSettings);\n\n    const client = NightwatchClient.client(settings, null, argv);\n    const {transport} = client;\n    transport.createSessionBuilder = function() {\n      return createMockDriverBuilder();\n    };\n\n    const session = await transport.createSession({argv: {}, moduleKey: 'testModuleKey'});\n\n    return {\n      session,\n      serverPath,\n      serverPort,\n      buildArgs\n    };\n  }\n\n  it('test create session with chrome driver', async function() {\n    mockery.registerMock('chromedriver', {\n      path: '/path/to/chromedriver'\n    });\n\n    const {session, serverPath, serverPort} = await ChromeDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n    assert.strictEqual(serverPath, '/path/to/chromedriver');\n    assert.strictEqual(serverPort, 9999);\n  });\n\n  it('test create session with chrome driver -- random port', async function() {\n    mockery.registerMock('chromedriver', {\n      path: '/path/to/chromedriver'\n    });\n\n    const {session, serverPath, serverPort} = await ChromeDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      webdriver: {\n        start_process: true\n      }\n    }, {\n      parallel: true\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: undefined\n    });\n    assert.strictEqual(serverPath, '/path/to/chromedriver');\n    assert.strictEqual(serverPort, undefined);\n  });\n\n  it('test chrome logging is absent in creating session with chrome driver on windows', async () => {\n    const platform = process.platform;\n    Object.defineProperty(process, 'platform', {\n      value: 'win32'\n    });\n\n    mockery.registerMock('chromedriver', {\n      path: '/path/to/chromedriver'\n    });\n\n    const {session, serverPath, serverPort, buildArgs} = await ChromeDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111',\n      host: 'localhost',\n      port: 9999,\n      capabilities: {}\n    });\n    assert.strictEqual(serverPath, '/path/to/chromedriver');\n    assert.strictEqual(serverPort, 9999);\n    assert.deepStrictEqual(buildArgs, ['--verbose']);\n\n    Object.defineProperty(process, 'platform', {\n      value: platform\n    });\n  });\n\n  it('test chrome logging is present in creating session with chrome driver on mac', async () => {\n    const platform = process.platform;\n    Object.defineProperty(process, 'platform', {\n      value: 'darwin'\n    });\n\n    mockery.registerMock('chromedriver', {\n      path: '/path/to/chromedriver'\n    });\n\n    const {session, serverPath, serverPort, buildArgs} = await ChromeDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111',\n      host: 'localhost',\n      port: 9999,\n      capabilities: {}\n    });\n    assert.strictEqual(serverPath, '/path/to/chromedriver');\n    assert.strictEqual(serverPort, 9999);\n    assert.deepStrictEqual(buildArgs, ['--verbose', '--enable-chrome-logs']);\n\n    Object.defineProperty(process, 'platform', {\n      value: platform\n    });\n  });\n\n  it('test verbose logging is absent when --silent cli_arg is used.', async () => {\n    mockery.registerMock('chromedriver', {\n      path: '/path/to/chromedriver'\n    });\n\n    const {session, serverPath, serverPort, buildArgs} = await ChromeDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true,\n        cli_args: [\n          '--silent'\n        ]\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111',\n      host: 'localhost',\n      port: 9999,\n      capabilities: {}\n    });\n    assert.strictEqual(serverPath, '/path/to/chromedriver');\n    assert.strictEqual(serverPort, 9999);\n\n    const expectedBuildArgs = ['--silent'];\n    if (process.platform !== 'win32') {\n      expectedBuildArgs.push('--enable-chrome-logs');\n    }\n    assert.deepStrictEqual(buildArgs, expectedBuildArgs);\n  });\n\n  it('test verbose logging is absent when --log-level cli_arg is used.', async () => {\n    mockery.registerMock('chromedriver', {\n      path: '/path/to/chromedriver'\n    });\n\n    const {session, serverPath, serverPort, buildArgs} = await ChromeDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true,\n        cli_args: [\n          '--log-level=WARNING',\n          '--version'\n        ]\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111',\n      capabilities: {},\n      host: 'localhost',\n      port: 9999\n    });\n    assert.strictEqual(serverPath, '/path/to/chromedriver');\n    assert.strictEqual(serverPort, 9999);\n\n    const expectedBuildArgs = ['--log-level=WARNING', '--version'];\n    if (process.platform !== 'win32') {\n      expectedBuildArgs.push('--enable-chrome-logs');\n    }\n    assert.deepStrictEqual(buildArgs, expectedBuildArgs);\n  });\n});\n"
  },
  {
    "path": "test/src/service-builders/testEdgeDriver.js",
    "content": "const assert = require('assert');\nconst mockery = require('mockery');\nconst common = require('../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst Settings = common.require('settings/settings.js');\n\ndescribe('EdgeDriver Transport Tests', function () {\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n\n    const {constants, rmdirSync} = require('fs');\n\n    delete require.cache['fs'];\n\n    mockery.registerMock('fs', {\n      existsSync() {\n        return true;\n      },\n      constants,\n      rmdirSync,\n      readFileSync() {\n        return true;\n      }\n    });\n\n  });\n\n  afterEach(function(){\n    mockery.deregisterAll();\n    mockery.disable();\n    mockery.resetCache();\n  });\n\n  const sessionData = {\n    sessionId: '111',\n    getId() {\n      return '1111';\n    },\n    getCapabilities() {\n      return {\n        getPlatform() {\n          return 'MAC';\n        },\n        getBrowserName() {\n          return 'MicrosoftEdge';\n        },\n        getBrowserVersion() {\n          return '11';\n        },\n        get(name) {\n          return name;\n        },\n        keys() {\n          return new Map();\n        }\n      };\n    }\n  };\n\n  const mockDriver = {\n    session_: Promise.resolve(),\n    async getSession() {\n      return sessionData;\n    },\n    async getExecutor() {\n      return {\n        w3c: true\n      };\n    }\n  };\n\n  const fn = function() {};\n  function deleteFromRequireCache(location) {\n    const entry = Object.keys(require.cache).filter(item => {\n      return item.includes(location);\n    });\n\n    entry.forEach(item => {\n      delete require.cache[item];\n    });\n  }\n\n  function createMockDriverBuilder() {\n    const {Builder} = require('selenium-webdriver');\n    class MockBuilder extends Builder {\n      build() {\n        return Promise.resolve(mockDriver);\n      }\n    }\n\n    return new MockBuilder();\n  }\n\n  function mockServiceBuilder({onConstruct = fn, onAddArguments = fn, onSetPort = fn, onSetHostname = fn, onSetPath = fn}) {\n    const edge = require('selenium-webdriver/edge');\n    const {Options, ServiceBuilder} = edge;\n\n    deleteFromRequireCache('node_modules/selenium-webdriver/edge');\n\n    class MockServiceBuilder extends ServiceBuilder {\n      constructor(server_path) {\n        super(server_path);\n\n        onConstruct.call(this, server_path);\n      }\n\n      setPort(port) {\n        onSetPort(port);\n      }\n\n      setHostname(h) {\n        onSetHostname(h);\n      }\n\n      setPath(h) {\n        onSetPath(h);\n      }\n\n      addArguments(...args) {\n        onAddArguments(args);\n      }\n\n      enableChromeLogging() {\n        return this;\n      }\n\n      build() {\n        return {\n          kill() {\n\n          },\n          async start() {\n            return 'http://localhost';\n          }\n        };\n      }\n    }\n\n    mockery.registerMock('selenium-webdriver/edge', {\n      Options,\n      ServiceBuilder: MockServiceBuilder\n    });\n  }\n\n  async function EdgeDriverTestSetup(useSettings, argv = {}) {\n    const BaseService = common.require('transport/selenium-webdriver/service-builders/base-service.js');\n    class MockBaseService extends BaseService {\n      constructor(settings) {\n        super(settings);\n\n        this.setOutputFile('');\n\n        assert.strictEqual(this.serviceName, 'EdgeDriver');\n        assert.strictEqual(this.outputFile, '_msedgedriver.log');\n        assert.strictEqual(this.defaultPort, undefined);\n        assert.strictEqual(this.npmPackageName, null);\n        assert.strictEqual(this.serviceDownloadUrl, 'https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/');\n      }\n\n      needsSinkProcess() {\n        return true;\n      }\n      hasSinkSupport() {\n        return true;\n      }\n      async writeLogFile() {\n      }\n      async createSinkProcess() {\n\n      }\n    }\n\n    deleteFromRequireCache('transport/selenium-webdriver/service-builders/base-service.js');\n    mockery.registerMock('./base-service.js', MockBaseService);\n\n    let serverPath;\n    let serverPort;\n    const buildArgs = [];\n    let logFilePath;\n\n    mockServiceBuilder({\n      onConstruct(server_path) {\n        serverPath = server_path;\n      },\n\n      onAddArguments(args) {\n        buildArgs.push(...args);\n      },\n\n      onSetPort(p) {\n        serverPort = p;\n      }\n    });\n\n    const Transport = common.require('transport/selenium-webdriver/edge.js');\n    const settings = Settings.parse(useSettings);\n\n    const client = NightwatchClient.client(settings, null, argv);\n    const {transport} = client;\n    //const transport = new Transport(client, 'MicrosoftEdge');\n    transport.createSessionBuilder = function() {\n      return createMockDriverBuilder();\n    };\n\n    const session = await transport.createSession({argv: {}, moduleKey: 'testModuleKey'});\n\n    return {\n      session,\n      serverPath,\n      serverPort,\n      buildArgs\n    };\n  }\n\n  it('test create session with edge driver', async function() {\n    const {session, serverPath, serverPort, buildArgs} = await EdgeDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'MicrosoftEdge'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true,\n        server_path: '/path/to/edgedriver'\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n    assert.strictEqual(serverPath, '/path/to/edgedriver');\n    assert.strictEqual(serverPort, 9999);\n    assert.deepStrictEqual(buildArgs, ['--verbose']);\n  });\n\n  it('test create session with edge driver -- random port', async function() {\n    const {session, serverPath, serverPort, buildArgs} = await EdgeDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'MicrosoftEdge'\n      },\n      webdriver: {\n        start_process: true,\n        server_path: '/path/to/edgedriver'\n      }\n    }, {parallel: true});\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: undefined\n    });\n    assert.strictEqual(serverPath, '/path/to/edgedriver');\n    assert.strictEqual(serverPort, undefined);\n    assert.deepStrictEqual(buildArgs, ['--verbose']);\n  });\n\n  it('test verbose logging is absent when --silent cli_arg is used.', async () => {\n    const {session, serverPath, serverPort, buildArgs} = await EdgeDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'edge'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true,\n        server_path: '/path/to/edgedriver',\n        cli_args: [\n          '--silent'\n        ]\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n    assert.strictEqual(serverPath, '/path/to/edgedriver');\n    assert.strictEqual(serverPort, 9999);\n    assert.deepStrictEqual(buildArgs, ['--silent']);\n  });\n\n  it('test verbose logging is absent when --log-level cli_arg is used.', async () => {\n    const {session, serverPath, serverPort, buildArgs} = await EdgeDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'edge'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true,\n        server_path: '/path/to/edgedriver',\n        cli_args: [\n          '--log-level=SEVERE'\n        ]\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n    assert.strictEqual(serverPath, '/path/to/edgedriver');\n    assert.strictEqual(serverPort, 9999);\n    assert.deepStrictEqual(buildArgs, ['--log-level=SEVERE']);\n  });\n});\n"
  },
  {
    "path": "test/src/service-builders/testFirefoxDriver.js",
    "content": "const assert = require('assert');\nconst mockery = require('mockery');\nconst common = require('../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst Settings = common.require('settings/settings.js');\nconst HttpRequest = common.require('http/request.js');\nconst HttpClient = common.require('transport/selenium-webdriver/httpclient.js')({});\n\ndescribe('GeckoDriver Transport Tests', function () {\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n\n    const {constants, rmdirSync} = require('fs');\n\n    delete require.cache['fs'];\n\n    mockery.registerMock('fs', {\n      existsSync() {\n        return true;\n      },\n      constants,\n      rmdirSync,\n      readFileSync() {\n        return true;\n      }\n    });\n\n  });\n\n  afterEach(function(){\n    mockery.deregisterAll();\n    mockery.disable();\n    mockery.resetCache();\n  });\n\n  const RANDOM_PORT = 6732;\n  \n  const sessionData = {\n    sessionId: '111',\n    getId() {\n      return '1111';\n    },\n    getCapabilities() {\n      return {\n        getPlatform() {\n          return 'MAC';\n        },\n        getBrowserName() {\n          return 'firefox';\n        },\n        getBrowserVersion() {\n          return '11';\n        },\n        get(name) {\n          return name;\n        },\n        keys() {\n          return new Map();\n        }\n      };\n    }\n  };\n\n  const mockDriver = {\n    session_: Promise.resolve(),\n    async getSession() {\n      return sessionData;\n    },\n    async getExecutor() {\n      return {\n        w3c: true\n      };\n    }\n  };\n\n  const fn = function() {};\n  function deleteFromRequireCache(location) {\n    const entry = Object.keys(require.cache).filter(item => {\n      return item.includes(location);\n    });\n\n    entry.forEach(item => {\n      delete require.cache[item];\n    });\n  }\n\n  function createMockDriverBuilder() {\n    const {Builder} = require('selenium-webdriver');\n    class MockBuilder extends Builder {\n      build() {\n        const httpClient =  new HttpClient(`http://localhost:${RANDOM_PORT}`);\n\n        return Promise.resolve(mockDriver);\n      }\n    }\n\n    return new MockBuilder();\n  }\n\n  function mockServiceBuilder({onConstruct = fn, onEnableVerboseLogging = fn, onAddArguments = fn, onSetPort = fn, onSetHostname = fn, onSetPath = fn}) {\n    const firefox = require('selenium-webdriver/firefox');\n    const {Options, ServiceBuilder} = firefox;\n\n    deleteFromRequireCache('node_modules/selenium-webdriver/firefox');\n\n    class MockServiceBuilder extends ServiceBuilder {\n      constructor(server_path) {\n        super(server_path);\n\n        onConstruct.call(this, server_path);\n      }\n\n      setPort(port) {\n        onSetPort(port);\n      }\n\n      setHostname(h) {\n        onSetHostname(h);\n      }\n\n      setPath(h) {\n        onSetPath(h);\n      }\n\n      addArguments(...args) {\n        onAddArguments(args);\n      }\n\n      build() {\n        return {\n          kill() {\n\n          },\n          async start() {\n            return 'http://localhost';\n          }\n        };\n      }\n    }\n\n    mockery.registerMock('selenium-webdriver/firefox', {\n      Options,\n      ServiceBuilder: MockServiceBuilder\n    });\n  }\n\n  async function GeckoDriverTestSetup(useSettings, argv = {}) {\n    const BaseService = common.require('transport/selenium-webdriver/service-builders/base-service.js');\n    class MockBaseService extends BaseService {\n      constructor(settings) {\n        super(settings);\n\n        this.setOutputFile('');\n\n        assert.strictEqual(this.serviceName, 'GeckoDriver');\n        assert.strictEqual(this.outputFile, '_geckodriver.log');\n        assert.strictEqual(this.requiresDriverBinary, false);\n        assert.strictEqual(this.defaultPort, undefined);\n        assert.strictEqual(this.npmPackageName, 'geckodriver');\n        assert.strictEqual(this.serviceDownloadUrl, 'https://github.com/mozilla/geckodriver/releases');\n      }\n\n      needsSinkProcess() {\n        return true;\n      }\n      hasSinkSupport() {\n        return true;\n      }\n      async writeLogFile() {\n      }\n      async createSinkProcess() {\n\n      }\n    }\n\n    deleteFromRequireCache('transport/selenium-webdriver/service-builders/base-service.js');\n    mockery.registerMock('./base-service.js', MockBaseService);\n\n    let serverPath;\n    let serverPort;\n    const buildArgs = [];\n\n    mockServiceBuilder({\n      onConstruct(server_path) {\n        serverPath = server_path;\n      },\n\n      onAddArguments(args) {\n        buildArgs.push(...args);\n      },\n\n      onSetPort(p) {\n        serverPort = p;\n      }\n    });\n\n    const Transport = common.require('transport/selenium-webdriver/firefox.js');\n    const settings = Settings.parse(useSettings);\n\n    const client = NightwatchClient.client(settings, null, argv);\n    const {transport} = client;\n    transport.createSessionBuilder = function() {\n      return createMockDriverBuilder();\n    };\n\n    const session = await transport.createSession({argv: {}, moduleKey: 'testModuleKey'});\n\n    return {\n      session,\n      serverPath,\n      serverPort,\n      buildArgs\n    };\n  }\n\n  it('test create session with firefox driver', async function() {\n    mockery.registerMock('geckodriver', {\n      path: '/path/to/geckodriver'\n    });\n\n    const {session, serverPath, serverPort, buildArgs} = await GeckoDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n    assert.strictEqual(serverPath, '/path/to/geckodriver');\n    assert.strictEqual(serverPort, 9999);\n    assert.deepStrictEqual(buildArgs, ['-vv']);\n  });\n\n  it('test create session with gecko driver -- random port', async function() {\n    mockery.registerMock('geckodriver', {\n      path: '/path/to/geckodriver'\n    });\n\n    const {session, serverPath, serverPort, buildArgs} = await GeckoDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      webdriver: {\n        start_process: true\n      }\n    }, {\n      parallel: true\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: undefined\n    });\n    assert.strictEqual(serverPath, '/path/to/geckodriver');\n    assert.strictEqual(serverPort, undefined);\n    assert.deepStrictEqual(buildArgs, ['-vv']);\n\n    //Global port should be set to random assigned Port\n    assert.strictEqual(HttpRequest.globalSettings.port, RANDOM_PORT);\n  });\n\n  it('test verbose logging is absent when --log cli_arg is used.', async () => {\n    mockery.registerMock('geckodriver', {\n      path: '/path/to/geckodriver'\n    });\n\n    const {session, serverPath, serverPort, buildArgs} = await GeckoDriverTestSetup({\n      desiredCapabilities: {\n        browserName: 'firefox'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true,\n        cli_args: [\n          '--log', 'fatal'\n        ]\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n    assert.strictEqual(serverPath, '/path/to/geckodriver');\n    assert.strictEqual(serverPort, 9999);\n    assert.deepStrictEqual(buildArgs, ['--log', 'fatal']);\n  });\n});\n"
  },
  {
    "path": "test/src/service-builders/testSafariDriver.js",
    "content": "const assert = require('assert');\nconst mockery = require('mockery');\nconst common = require('../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst Settings = common.require('settings/settings.js');\nconst path = require('path');\nconst MockServer = require('../../lib/mockserver.js');\nconst {settings} = common;\nconst {runTests} = common.require('index.js');\n\ndescribe('SafariDriver Transport Tests', function () {\n  before(function(done) {\n    this.server = MockServer.init();\n\n    this.server.on('listening', () => {\n      done();\n    });\n  });\n\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n  });\n\n  afterEach(function(){\n    mockery.deregisterAll();\n    mockery.disable();\n    mockery.resetCache();\n  });\n\n  after(function(done) {\n    this.server.close(function() {\n      done();\n    });\n  });\n\n  const fn = function() {};\n  function deleteFromRequireCache(location) {\n    const entry = Object.keys(require.cache).filter(item => {\n      return item.includes(location);\n    });\n\n    entry.forEach(item => {\n      delete require.cache[item];\n    });\n  }\n\n  function mockExecutor(results) {\n    const {Executor, HttpClient} = require('selenium-webdriver/http');\n    class MockExecutor extends Executor {\n      async execute(command) {\n        return Promise.resolve(results);\n      }\n    }\n\n    deleteFromRequireCache('node_modules/selenium-webdriver/http');\n\n    mockery.registerMock('selenium-webdriver/http', {\n      Executor: MockExecutor,\n      HttpClient\n    });\n  }\n\n\n  function mockServiceBuilder({onConstruct = fn, onAddArguments = fn, onSetPort = fn, onSetHostname = fn, onSetPath = fn}) {\n    const safari = require('selenium-webdriver/safari');\n    const {Options, ServiceBuilder} = safari;\n\n    deleteFromRequireCache('node_modules/selenium-webdriver/safari');\n\n    class MockServiceBuilder /*extends ServiceBuilder*/ {\n      constructor(server_path) {\n        onConstruct.call(this, server_path);\n      }\n\n      setPort(port) {\n        onSetPort(port);\n      }\n\n      setHostname(h) {\n        onSetHostname(h);\n      }\n\n      setPath(h) {\n        onSetPath(h);\n      }\n\n      addArguments(args) {\n        onAddArguments(args);\n      }\n\n      build() {\n        return {\n          kill() {\n\n          },\n          async start() {\n            return 'http://localhost';\n          }\n        };\n      }\n    }\n\n    mockery.registerMock('selenium-webdriver/safari', {\n      Options,\n      ServiceBuilder: MockServiceBuilder\n    });\n  }\n\n  async function SafariTestSetup(useSettings, {onLogFile = fn} = {}) {\n    mockExecutor({\n      sessionId: '111',\n      getId() {\n        return '1111';\n      },\n      getCapabilities() {\n        return {\n          getPlatform() {\n            return 'MAC';\n          },\n          getBrowserName() {\n            return 'safari';\n          },\n          getBrowserVersion() {\n            return '11';\n          },\n          get(name) {\n            return name;\n          },\n          keys() {\n            return new Map();\n          }\n        };\n      }\n    });\n\n    const BaseService = common.require('transport/selenium-webdriver/service-builders/base-service.js');\n    class MockBaseService extends BaseService {\n      constructor(settings) {\n        super(settings);\n\n        this.setOutputFile('');\n\n        assert.strictEqual(this.serviceName, 'SafariDriver');\n        assert.strictEqual(this.outputFile, '_safaridriver.log');\n        assert.strictEqual(this.requiresDriverBinary, false);\n        assert.strictEqual(this.defaultPort, 0);\n      }\n      needsSinkProcess() {\n        return true;\n      }\n      hasSinkSupport() {\n        return true;\n      }\n      async writeLogFile() {\n      }\n      async createSinkProcess() {\n        const logPath = this.getLogPath();\n        if (!logPath) {\n          return true;\n        }\n\n        const filePath = this.getOutputFilePath();\n        onLogFile(filePath);\n      }\n    }\n\n    deleteFromRequireCache('transport/selenium-webdriver/service-builders/base-service.js');\n    mockery.registerMock('./base-service.js', MockBaseService);\n\n    let serverPath;\n    let serverPort;\n    let buildArgs;\n    let logFilePath;\n\n    mockServiceBuilder({\n      onConstruct(server_path) {\n        serverPath = server_path;\n      },\n\n      onAddArguments(args) {\n        buildArgs = args;\n      },\n\n      onSetPort(p) {\n        serverPort = p;\n      }\n    });\n\n    const Transport = common.require('transport/selenium-webdriver/safari.js');\n    const settings = Settings.parse(useSettings);\n\n    const client = NightwatchClient.client(settings, null, {});\n    const transport = new Transport(client, {browserName: 'safari'});\n\n    const session = await transport.createSession({argv: {}, moduleKey: 'testModuleKey'});\n\n    return {\n      session,\n      serverPath,\n      serverPort\n    };\n  }\n\n  it('test create session with safari driver', async function() {\n    let logFilePath;\n    const {session, serverPath, serverPort} = await SafariTestSetup({\n      desiredCapabilities: {\n        browserName: 'safari'\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true\n      }\n    }, {\n      onLogFile(filePath) {\n        logFilePath = filePath;\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n    assert.strictEqual(serverPath, '/usr/bin/safaridriver');\n    assert.strictEqual(serverPort, 9999);\n    assert.ok(logFilePath.endsWith(`logs${path.sep}testModuleKey_safaridriver.log`), logFilePath);\n  });\n\n  it('test create session with safari driver -- random port', async function() {\n    const {session, serverPath, serverPort} = await SafariTestSetup({\n      desiredCapabilities: {\n        browserName: 'safari'\n      },\n      webdriver: {\n        start_process: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: undefined\n    });\n    assert.strictEqual(serverPath, '/usr/bin/safaridriver');\n    assert.strictEqual(serverPort, undefined);\n  });\n\n  it('test create session with safari driver using technologyPreview', async function() {\n    const {session, serverPath} = await SafariTestSetup({\n      desiredCapabilities: {\n        browserName: 'safari',\n        'safari.options': {\n          technologyPreview: true\n        }\n      },\n      webdriver: {\n        port: 9999,\n        start_process: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n    assert.strictEqual(serverPath, '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver');\n  });\n\n  it('session create should throw error after max retryAttempts', function() {\n\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/async')\n    ];\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 500,\n      postdata: JSON.stringify({\n        'capabilities': {'firstMatch': [{}], 'alwaysMatch': {'browserName': 'safari', 'safari:options': {}}}\n      }),\n      response: JSON.stringify({\n        value: {\n          error: 'session not created',\n          message: 'Could not create a session: Some devices were found, but could not be used:\\n'\n        }\n      }),\n      times: 2\n    });\n\n    const globals = {\n      reporter(results) {\n        const sep = path.sep;\n        assert.strictEqual(results.errors, 1);\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n        assert.ok(Object.keys(results.modules).includes(`test${sep}sample`));\n        assert.ok(results.lastError instanceof Error);\n\n        assert.strictEqual(results.lastError.message, 'An error occurred while creating a new SafariDriver session: [SessionNotCreatedError] Could not create a session: Some devices were found, but could not be used:\\n');\n      }\n    };\n\n    return runTests({source: testsPath}, settings({\n      selenium_host: null,\n      desiredCapabilities: {\n        browserName: 'safari'\n      },\n      webdriver: {\n        host: 'localhost',\n        timeout_options: {\n          retry_attempts: 1\n        },\n        internal_server_error_retry_interval: 0\n      },\n      globals,\n      output: false,\n      output_folder: false\n    }));\n  });\n\n  it('session create should retry on internal server error (500)', function() {\n    const testsPath = [\n      path.join(__dirname, '../../sampletests/async')\n    ];\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 500,\n      postdata: JSON.stringify({\n        'capabilities': {'firstMatch': [{}], 'alwaysMatch': {'browserName': 'safari', 'safari:options': {}}}\n      }),\n      response: JSON.stringify({\n        value: {\n          error: 'session not created',\n          message: 'Could not create a session: Some devices were found, but could not be used:\\n'\n        }\n      }),\n      times: 3\n    });\n\n    MockServer.addMock({\n      url: '/session',\n      statusCode: 200,\n      postdata: JSON.stringify({\n        'capabilities': {'firstMatch': [{}], 'alwaysMatch': {'browserName': 'safari', 'safari:options': {}}}\n      }),\n      response: JSON.stringify({\n        value: {\n          sessionId: 'D5E59FB5-1DBA-4ED8-9402-459D9A4AA0D7',\n          capabilities: {\n            'safari:deviceName': 'Binayak\\'s iPhone',\n            'safari:platformVersion': '16.2'\n          }\n        }\n      }),\n      times: 1\n    });\n\n    const globals = {\n      reporter(results) {\n        const sep = path.sep;\n        assert.strictEqual(results.errors, 0);\n        assert.strictEqual(Object.keys(results.modules).length, 1);\n        assert.ok(Object.keys(results.modules).includes(`test${sep}sample`));\n      }\n    };\n\n    return runTests({source: testsPath}, settings({\n      selenium_host: null,\n      desiredCapabilities: {\n        browserName: 'safari'\n      },\n      webdriver: {\n        host: 'localhost',\n        timeout_options: {\n          retry_attempts: 3\n        },\n        internal_server_error_retry_interval: 100\n      },\n      globals,\n      output: false,\n      output_folder: false\n    }));\n  });\n});\n"
  },
  {
    "path": "test/src/service-builders/testSeleniumServer.js",
    "content": "const assert = require('assert');\nconst mockery = require('mockery');\nconst common = require('../../common.js');\nconst NightwatchClient = common.require('index.js');\nconst Settings = common.require('settings/settings.js');\n\ndescribe('SeleniumServer Transport Tests', function () {\n  beforeEach(function() {\n    mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n  });\n\n  afterEach(function(){\n    mockery.deregisterAll();\n    mockery.disable();\n    mockery.resetCache();\n  });\n\n  const sessionData = {\n    sessionId: '111',\n    getId() {\n      return '1111';\n    },\n    getCapabilities() {\n      return {\n        getPlatform() {\n          return 'MAC';\n        },\n        getBrowserName() {\n          return 'chrome';\n        },\n        getBrowserVersion() {\n          return '11';\n        },\n        get(name) {\n          return name;\n        },\n        keys() {\n          return new Map();\n        }\n      };\n    }\n  };\n\n  const mockDriver = {\n    session_: Promise.resolve(),\n    async getSession() {\n      return sessionData;\n    },\n    async getExecutor() {\n      return {\n        w3c: true\n      };\n    }\n  };\n\n  const fn = function() {};\n  function deleteFromRequireCache(location) {\n    const entry = Object.keys(require.cache).filter(item => {\n      return item.includes(location);\n    });\n\n    entry.forEach(item => {\n      delete require.cache[item];\n    });\n  }\n\n  function mockExecutor(results) {\n    const {Executor, HttpClient} = require('selenium-webdriver/http');\n    class MockExecutor extends Executor {\n      async execute(command) {\n        return Promise.resolve(results);\n      }\n    }\n\n    deleteFromRequireCache('node_modules/selenium-webdriver/http');\n\n    mockery.registerMock('selenium-webdriver/http', {\n      Executor: MockExecutor,\n      HttpClient\n    });\n  }\n\n  function createMockDriverBuilder() {\n    const {Builder} = require('selenium-webdriver');\n    class MockBuilder extends Builder {\n      build() {\n        return Promise.resolve(mockDriver);\n      }\n    }\n\n    return new MockBuilder();\n  }\n\n\n  function mockServiceBuilder({onConstruct = fn, onOpts = fn, onSetPort = fn}) {\n    const remote = require('selenium-webdriver/remote');\n    const {Options, SeleniumServer, DriverService} = remote;\n\n    deleteFromRequireCache('node_modules/selenium-webdriver/remote');\n\n    class MockSeleniumServer {\n      constructor(jar, opts) {\n        onConstruct.call(this, jar);\n        if (opts.port) {\n          onSetPort(opts.port);\n        }\n        onOpts(opts);\n      }\n\n      async start() {\n        return {};\n      }\n    }\n\n    class MockDriverService {\n      constructor(command, opts) {\n        onConstruct.call(this, command);\n\n        if (opts.port) {\n          onSetPort(opts.port);\n        }\n\n        onOpts(opts);\n      }\n\n      async start() {\n        return {};\n      }\n    }\n\n    MockSeleniumServer.Options = SeleniumServer.Options;\n\n    mockery.registerMock('selenium-webdriver/remote', {\n      Options,\n      SeleniumServer: MockSeleniumServer,\n      DriverService: MockDriverService\n    });\n  }\n\n  async function SeleniumServerTestSetup(useSettings, {selenium4 = false, onLogFile = fn} = {}) {\n    const BaseService = common.require('transport/selenium-webdriver/service-builders/base-service.js');\n    class MockBaseService extends BaseService {\n      constructor(settings) {\n        super(settings);\n\n        this.setOutputFile('');\n\n        assert.strictEqual(this.serviceName, 'Selenium Server');\n        assert.strictEqual(this.outputFile, '_selenium-server.log');\n        assert.strictEqual(this.defaultPort, 4444);\n        assert.strictEqual(this.usingSelenium4(), selenium4);\n        assert.strictEqual(this.npmPackageName, '@nightwatch/selenium-server');\n        assert.strictEqual(this.serviceDownloadUrl, 'https://selenium.dev/download/');\n        assert.strictEqual(this.downloadMessage, 'download the selenium server jar from https://selenium.dev/download/, \\n and set \"selenium.server_path\" config option to point to the jar file.');\n      }\n      needsSinkProcess() {\n        return true;\n      }\n      hasSinkSupport() {\n        return true;\n      }\n      async writeLogFile() {\n      }\n      async createSinkProcess() {\n        this.process = {\n          kill: () => {}\n        };\n        const logPath = this.getLogPath();\n        if (!logPath) {\n          return true;\n        }\n\n        const filePath = this.getOutputFilePath();\n        onLogFile(filePath);\n      }\n    }\n\n    deleteFromRequireCache('transport/selenium-webdriver/service-builders/base-service.js');\n    mockery.registerMock('./base-service.js', MockBaseService);\n\n    let serverPath;\n    let serverPort;\n    let buildArgs;\n    let logFilePath;\n    let options;\n\n    mockServiceBuilder({\n      onConstruct(server_path) {\n        serverPath = server_path;\n      },\n\n      onAddArguments(args) {\n        buildArgs = args;\n      },\n\n      onSetPort(p) {\n        serverPort = p;\n      },\n\n      onOpts(o) {\n        options = o;\n      }\n    });\n\n    const settings = Settings.parse(useSettings);\n\n    const client = NightwatchClient.client(settings, null, {});\n    const {transport} = client;\n    transport.createSessionBuilder = function() {\n      return createMockDriverBuilder();\n    };\n\n    const session = await transport.createSession({argv: {}, moduleKey: 'testModuleKey'});\n\n    return {\n      session,\n      serverPath,\n      serverPort,\n      options\n    };\n  }\n\n  it('test create session with selenium server 3', async function() {\n    mockery.registerMock('geckodriver', {\n      path: ''\n    });\n\n    mockery.registerMock('chromedriver', {\n      path: ''\n    });\n\n    mockery.registerMock('@nightwatch/selenium-server', {\n      path: '/path/to/selenium-server-standalone.3.0.jar'\n    });\n\n    let logFilePath;\n    const {session, serverPath, serverPort, options} = await SeleniumServerTestSetup({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium: {\n        port: 9999,\n        start_process: true\n      }\n    }, {\n      onLogFile(filePath) {\n        logFilePath = filePath;\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n    assert.strictEqual(serverPath, '/path/to/selenium-server-standalone.3.0.jar');\n    assert.strictEqual(serverPort, 9999);\n    assert.strictEqual(options.port, 9999);\n    assert.deepStrictEqual(options.args, []);\n    assert.deepStrictEqual(options.jvmArgs, []);\n    assert.deepStrictEqual(options.stdio, ['pipe', undefined, undefined]);\n    assert.ok(logFilePath.endsWith('testModuleKey_selenium-server.log'));\n  });\n\n  it('test create session with selenium server 3 -- with drivers', async function() {\n    mockery.registerMock('geckodriver', {\n      path: '/path/to/geckodriver'\n    });\n\n    mockery.registerMock('chromedriver', {\n      path: '/path/to/chromedriver'\n    });\n\n    mockery.registerMock('@nightwatch/selenium-server', {\n      path: '/path/to/selenium-server-standalone.3.0.jar'\n    });\n\n    let logFilePath;\n    const {session, serverPath, serverPort, options} = await SeleniumServerTestSetup({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium: {\n        port: 9999,\n        start_process: true,\n        cli_args: {\n          '-timeout': 1000\n        }\n      }\n    }, {\n      onLogFile(filePath) {\n        logFilePath = filePath;\n      }\n    });\n\n    assert.strictEqual(serverPath, '/path/to/selenium-server-standalone.3.0.jar');\n    assert.deepStrictEqual(options.args, ['-timeout', 1000]);\n    assert.deepStrictEqual(options.jvmArgs,  [\n      '-Dwebdriver.gecko.driver=/path/to/geckodriver',\n      '-Dwebdriver.chrome.driver=/path/to/chromedriver'\n    ]);\n    assert.deepStrictEqual(options.stdio, ['pipe', undefined, undefined]);\n    assert.ok(logFilePath.endsWith('testModuleKey_selenium-server.log'));\n  });\n\n  it('test create session with selenium server 3 -- random port', async function() {\n    mockery.registerMock('@nightwatch/selenium-server', {\n      path: '/path/to/selenium-server-standalone.3.0.jar'\n    });\n\n    const {session, serverPath, serverPort} = await SeleniumServerTestSetup({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium: {\n        port: null,\n        start_process: true\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: null\n    });\n    assert.strictEqual(serverPath, '/path/to/selenium-server-standalone.3.0.jar');\n    assert.ok(!!serverPort);\n  });\n\n  it('test create session with selenium server 4 -- and no drivers', async function() {\n    mockery.registerMock('geckodriver', {\n      path: ''\n    });\n\n    mockery.registerMock('chromedriver', {\n      path: ''\n    });\n\n    mockery.registerMock('@nightwatch/selenium-server', {\n      path: '/path/to/selenium-server.4.0.jar'\n    });\n\n    let logFilePath;\n    const {session, serverPath, serverPort, options} = await SeleniumServerTestSetup({\n      desiredCapabilities: {\n        browserName: 'chrome'\n      },\n      selenium: {\n        port: 9999,\n        command: 'standalone',\n        start_process: true,\n        cli_args: {\n          '--allow-cors': true\n        }\n      }\n    }, {\n      selenium4: true,\n      onLogFile(filePath) {\n        logFilePath = filePath;\n      }\n    });\n\n    assert.deepStrictEqual(session, {\n      sessionId: '1111', capabilities: {}, host: 'localhost', port: 9999\n    });\n\n    assert.strictEqual(serverPort, 9999);\n    assert.strictEqual(options.port, 9999);\n    assert.strictEqual(options.path, '/wd/hub');\n\n    assert.deepStrictEqual(options.args, [\n      '-jar',\n      '/path/to/selenium-server.4.0.jar',\n      'standalone',\n      '--port',\n      9999,\n      '--allow-cors',\n      true\n    ]);\n\n    assert.deepStrictEqual(options.stdio, ['pipe', undefined, undefined]);\n  });\n});\n"
  },
  {
    "path": "test/src/utils/__data__/meaning-of-life.js",
    "content": "module.exports = 42;\n"
  },
  {
    "path": "test/src/utils/__data__/meaning-of-life.mjs",
    "content": "export default 42;\n"
  },
  {
    "path": "test/src/utils/__data__/mixed-exports.mjs",
    "content": "const defaultExport = {\n  defaultValue: 'default-value',\n  defaultFunction: function() {\n    return 'default function called';\n  }\n};\n\nexport default defaultExport;\nexport const namedExport = 'named value';\nexport const namedFunction = function() {\n  return 'named function called';\n};\n"
  },
  {
    "path": "test/src/utils/__data__/named-exports.mjs",
    "content": "export const functionA = () => 'A';\nexport const functionB = () => 'B';\n"
  },
  {
    "path": "test/src/utils/testRequireModule.js",
    "content": "const {strict: assert} = require('node:assert');\nconst path = require('node:path');\n\nconst common = require('../../common.js');\nconst requireModule = common.require('utils/requireModule.js');\n\ndescribe('test requireModule', function () {\n  it('should load commonjs file', function () {\n    const modulePath = path.join(__dirname, './__data__/meaning-of-life.js');\n    const meaningOfLife = requireModule(modulePath);\n\n    assert.equal(meaningOfLife, 42);\n  });\n\n  it('should load es6 module', async function () {\n    const modulePath = path.join(__dirname, './__data__/meaning-of-life.mjs');\n    const meaningOfLife = await requireModule(modulePath);\n\n    assert.equal(meaningOfLife, 42);\n  });\n\n  it('should load es6 module with ts-node activated', async function () {\n    const tsNode = require('ts-node').register({\n      project: path.resolve('test', './tsconfig.json')\n    });\n\n    const modulePath = path.join(__dirname, './__data__/meaning-of-life.mjs');\n    // delete from cache to force reloading\n    delete require.cache[require.resolve(modulePath)];\n\n    const meaningOfLife = await requireModule(modulePath);\n\n    assert.equal(meaningOfLife, 42);\n    tsNode.enabled(false);\n  });\n\n  it('should load named exports from .mjs file', async function () {\n    const modulePath = path.join(__dirname, './__data__/named-exports.mjs');\n    const module = await requireModule(modulePath);\n\n    assert.equal(typeof module.functionA, 'function');\n    assert.equal(typeof module.functionB, 'function');\n  });\n\n  it('should load default and named exports from .mjs file', async function () {\n    const modulePath = path.join(__dirname, '__data__/mixed-exports.mjs');\n    const module = await requireModule(modulePath);\n\n    assert.equal(module.defaultValue, 'default-value');\n    assert.equal(module.defaultFunction(), 'default function called');\n    assert.equal(module.namedExport, 'named value');\n    assert.equal(module.namedFunction(), 'named function called');\n  });\n});\n"
  },
  {
    "path": "test/src/utils/testStackTrace.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst AssertionError = require('assertion-error');\nconst common = require('../../common.js');\nconst Utils = common.require('utils');\nconst beautifyStackTrace = common.require('utils/beautifyStackTrace.js');\nconst colors = common.require('utils/chalkColors.js');\nconst {Logger} = common.require('utils');\n\n\ndescribe('test stackTrace parse', function() {\n  before(() => {\n    colors.colors.level = 3;\n    colors.disable();\n  });\n  after(() => colors.enable());\n\n  it('filterStackTrace', function() {\n    let stackTrace = `Error\n        at Object.this test should fail and capture screenshot (/Projects/nightwatch/examples/tests/sample.js:5:16)\n        at Context.call (/node_modules/nightwatch/lib/testsuite/context.js:375:35\n        at TestCase.run (/node_modules/nightwatch/lib/testsuite/testcase.js:53:31\n        at Runnable.__runFn (/node_modules/nightwatch/lib/testsuite/index.js:376:80)\n        at Runnable.run (/node_modules/nightwatch/lib/tes….js:123:21)\n        at TestSuite.createRunnable (/node_modules/nightwatch/lib/testsuite/index.js:443:33)\n        at TestSuite.handleRunnable (/node_modules/nightwatch/lib/testsuite/index.js:448:18)\n        at /node_modules/nightwatch/lib/testsuite/index.js:376:21\n        at processTicksAndRejections (internal/process/task_queues.js:93:5)\n        at async DefaultRunner.runTestSuite (/node_modules/nightwatch/lib/runner/test-runners/default.js:68:7)`;\n    let expectedStackTrace = `Error\n        at Object.this test should fail and capture screenshot (/Projects/nightwatch/examples/tests/sample.js:5:16)`; \n    assert.strictEqual(Utils.filterStackTrace(stackTrace), expectedStackTrace);\n  \n    stackTrace = '';\n    expectedStackTrace = '';\n    assert.strictEqual(Utils.filterStackTrace(stackTrace), expectedStackTrace);\n  });\n\n  it('beautifyStackTrace -  read file lines (AssertionError)', async function() {\n\n    const errorFilePath = path.join(__dirname, '../../sampletests/withfailures/sample.js');\n    const lineNumber = 15;\n\n    const error = new AssertionError('Assertion Error');\n    error.stack = `Error\n      at DescribeInstance.<anonymous> (${errorFilePath}:${lineNumber}:23)\n      at Context.call (/Users/BarnOwl/Documents/Projects/Nightwatch/node_modules/nightwatch/lib/testsuite/context.js:430:35)\n      at TestCase.run (/Users/BarnOwl/Documents/Projects/Nightwatch/node_modules/nightwatch/lib/testsuite/testcase.js:58:31)\n      at Runnable.__runFn (/Users/BarnOwl/Documents/Projects/Nightwatch/node_modules/nightwatch/lib/testsuite/index.js:659:80)\n      at Runnable.run (/Users/BarnOwl/Documents/Projects/Nightwatch/node_modules/nightwatch/lib/testsuite/runnable.js:126:21)\n      at TestSuite.createRunnable (/Users/BarnOwl/Documents/Projects/Nightwatch/node_modules/nightwatch/lib/testsuite/index.js:766:33)\n      at TestSuite.handleRunnable (/Users/BarnOwl/Documents/Projects/Nightwatch/node_modules/nightwatch/lib/testsuite/index.js:771:33)\n      at /Users/BarnOwl/Documents/Projects/Nightwatch/node_modules/nightwatch/lib/testsuite/index.js:659:21\n      at processTicksAndRejections (node:internal/process/task_queues:96:5)`;\n\n    const delimiter = (new Array(errorFilePath.length + 3).join('–'));\n    const expected = ` ${errorFilePath}:15\n ${delimiter}\n  13 |     client.url('http://localhost')\n  14 |       .assert.elementPresent('#weblogin')\n  15 |       .assert.elementPresent('#badElement') \n  16 |       .assert.elementPresent('#webLogin')\n  17 |       .end();\n ${delimiter}\n`;\n\n    const result = beautifyStackTrace(error);\n    assert.strictEqual(result.replace(/\\s/g, ''), expected.replace(/\\s/g, ''));\n  });\n\n  it('beautifyStackTrace - Unknown API method', function() {\n    const errorFilePath = path.join(__dirname, '../../sampletests/unknown-method/UnknownMethod.js');\n    const lineNumber  = 4;\n\n    const error = new TypeError('Unknown method');\n    error.stack = `Error: Unknown api method \"elementPresen\".\n      at DescribeInstance.<anonymous> (${errorFilePath}:${lineNumber}:21)\n      at Context.call (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/context.js:430:35)\n      at TestCase.run (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/testcase.js:58:31)\n      at Runnable.__runFn (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:669:80)\n      at Runnable.run (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/runnable.js:126:21)\n      at TestSuite.createRunnable (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:776:33)\n      at TestSuite.handleRunnable (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:781:33)\n      at /Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:669:21\n      at processTicksAndRejections (node:internal/process/task_queues:96:5)`;\n\n    const delimiter = (new Array(errorFilePath.length + 3).join('–'));      \n    const expected = ` ${errorFilePath}:4\n ${delimiter}\n  2 |   it('failure stack trace', function() {\n  3 |    \n  4 |     browser.url('http://localhost') \n  5 |       .assert.elementPresen('#badElement'); // mispelled API method\n  6 |   });\n ${delimiter}\n`;\n\n    const result = Utils.beautifyStackTrace(error);\n    assert.strictEqual(result.replace(/\\s/g, ''), expected.replace(/\\s/g, ''));\n  });\n\n  it('should format error log properly', function() {\n    // Skip for windows\n    if (process.platform === 'win32') {\n      return;\n    }\n\n    colors.enable();\n    const errorFilePath = path.join(__dirname, '../../sampletests/unknown-method/UnknownMethod.js');\n    const lineNumber  = 4;\n\n    const error = new TypeError('Unknown method');\n    error.stack = `Error: Unknown api method \"elementPresen\".\n      at DescribeInstance.<anonymous> (${errorFilePath}:${lineNumber}:21)\n      at Context.call (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/context.js:430:35)\n      at TestCase.run (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/testcase.js:58:31)\n      at Runnable.__runFn (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:669:80)\n      at Runnable.run (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/runnable.js:126:21)\n      at TestSuite.createRunnable (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:776:33)\n      at TestSuite.handleRunnable (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:781:33)\n      at /Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:669:21\n      at processTicksAndRejections (node:internal/process/task_queues:96:5)`;\n    \n    const errorMessage = Logger.getErrorContent(error);\n    assert.ok(!errorMessage.includes('\\t'));\n\n    assert.strictEqual(errorMessage, ` \\x1B[31m\\x1B[1m✖\\x1B[22m\\x1B[39m \\x1B[31m\\x1B[1mTypeError\\x1B[22m\\x1B[39m\n   \\x1B[31mUnknown method\\x1B[39m\n\\x1B[33m\\x1B[39m\n\\x1B[33m    Error location:\\x1B[39m\n    ${errorFilePath}:4\n    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––\n     2 |   it('failure stack trace', function() {\n     3 |    \n    \\x1B[41m\\x1B[37m 4 |     browser.url('http://localhost') \\x1B[39m\\x1B[49m\n     5 |       .assert.elementPresen('#badElement'); // mispelled API method\n     6 |   });\n    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––\n\n\\x1B[33m    Stack Trace :\\x1B[39m\n\\x1B[90m    at DescribeInstance.<anonymous> (${errorFilePath}:${lineNumber}:21)\\x1B[39m\n\\x1B[90m      at Context.call (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/context.js:430:35)\\x1B[39m\n\\x1B[90m      at TestCase.run (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/testcase.js:58:31)\\x1B[39m\n\\x1B[90m      at Runnable.__runFn (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:669:80)\\x1B[39m\n\\x1B[90m      at Runnable.run (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/runnable.js:126:21)\\x1B[39m\n\\x1B[90m      at TestSuite.createRunnable (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:776:33)\\x1B[39m\n\\x1B[90m      at TestSuite.handleRunnable (/Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:781:33)\\x1B[39m\n\\x1B[90m      at /Users/BarnOwl/Documents/Projects/Nightwatch-tests/node_modules/nightwatch/lib/testsuite/index.js:669:21\\x1B[39m\n\\x1B[90m      at processTicksAndRejections (node:internal/process/task_queues:96:5)\\x1B[39m\n`);\n  });\n});\n"
  },
  {
    "path": "test/src/utils/testUtils.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst common = require('../../common.js');\nconst Utils = common.require('utils');\nconst mockery = require('mockery');\n\ndelete require.cache['fs'];\ndelete require.cache['path'];\n\ndescribe('test Utils', function() {\n\n  it('testFormatElapsedTime', function() {\n\n    const resultMs = Utils.formatElapsedTime(999);\n    assert.strictEqual(resultMs, '999ms');\n\n    const resultSec = Utils.formatElapsedTime(1999);\n    assert.strictEqual(resultSec, '1.999s');\n\n    const resultMin = Utils.formatElapsedTime(122299, true);\n    assert.strictEqual(resultMin, '2m 2s / 122299ms');\n  });\n\n  it('testMakeFnAsync', function() {\n    function asyncFn(cb) {\n      cb();\n    }\n\n    function syncFn() {\n    }\n\n    const convertedFn = Utils.makeFnAsync(1, syncFn);\n    let called = false;\n    convertedFn(function() {\n      called = true;\n    });\n\n    assert.strictEqual(Utils.makeFnAsync(1, asyncFn), asyncFn);\n    assert.ok(called);\n  });\n\n  it('testCheckFunction', function() {\n    const g = {\n      fn: function() {\n      }\n    };\n\n    const o = {\n      fn: false\n    };\n\n    const x = {\n      y: {\n        testFn: function() {\n        }\n      }\n    };\n\n    assert.ok(Utils.checkFunction('fn', g));\n    assert.ok(!Utils.checkFunction('fn', o));\n    assert.ok(Utils.checkFunction('testFn', x.y));\n  });\n\n  it('testGetTestSuiteName', function() {\n\n    assert.strictEqual(Utils.getTestSuiteName('test-case-one'), 'Test Case One');\n    assert.strictEqual(Utils.getTestSuiteName('test_case_two'), 'Test Case Two');\n    assert.strictEqual(Utils.getTestSuiteName('test.case.one'), 'Test Case One');\n    assert.strictEqual(Utils.getTestSuiteName('testCaseOne'), 'Test Case One');\n  });\n\n  it('testFlattenArrayDeep', function() {\n\n    assert.throws(() => {\n      Utils.flattenArrayDeep(null);\n    }, Error);\n    assert.throws(() => {\n      Utils.flattenArrayDeep({name: 'test'});\n    }, Error);\n    assert.throws(() => {\n      Utils.flattenArrayDeep('test');\n    }, Error);\n  });\n\n  it('testStripControlChars', function() {\n\n    assert.doesNotThrow(() => Utils.stripControlChars(null));\n    assert.strictEqual(\n      Utils.stripControlChars('\\x00rendered output'),\n      'rendered output'\n    );\n    assert.strictEqual(\n      Utils.stripControlChars('rendered \\x1Foutput'),\n      'rendered output'\n    );\n    assert.strictEqual(\n      Utils.stripControlChars('rendered output\\x7F'),\n      'rendered output'\n    );\n    assert.strictEqual(\n      Utils.stripControlChars('\\x00rendered\\x1F \\x1Boutput\\x9F\\x00'),\n      'rendered output'\n    );\n    assert.strictEqual(\n      Utils.stripControlChars(\n        '\\x00rendered output\\nrendered \\x1Foutput\\nrendered output\\x7F'\n      ),\n      'rendered output\\nrendered output\\nrendered output'\n    );\n    assert.strictEqual(\n      Utils.stripControlChars(\n        '\\x00rendered output\\rrendered \\x1Foutput\\rrendered output\\x7F'\n      ),\n      'rendered output\\rrendered output\\rrendered output'\n    );\n  });\n\n  it('testRelativeUrl', function() {\n    assert.strictEqual(Utils.relativeUrl('https://nightwatchjs.org'), false);\n    assert.strictEqual(Utils.relativeUrl('http://nightwatchjs.org'), false);\n    assert.strictEqual(Utils.relativeUrl('chrome-extension://pkehgijcmpdhfbdbbnkijodmdjhbjlgp/skin/options.html'), false);\n    assert.strictEqual(Utils.relativeUrl('nightwatchjs.org'), true);\n    assert.strictEqual(Utils.relativeUrl('nightwatchjs.org/guide'), true);\n    assert.strictEqual(Utils.relativeUrl('/guide'), true);\n  });\n\n  it('isTsFile', function() {\n    assert.strictEqual(Utils.isTsFile('/tests/sampleTest.ts'), true);\n    assert.strictEqual(Utils.isTsFile('/tests/sampleTest.js'), false);\n    assert.strictEqual(Utils.isTsFile('/tests/sampleTest.json'), false);\n    assert.strictEqual(Utils.isTsFile('/tests/sampleTest'), false);\n  });\n\n  it('isFileNameValid', function() {\n    assert.strictEqual(Utils.isFileNameValid('/tests/sampleTest.js'), true);\n    assert.strictEqual(Utils.isFileNameValid('/tests/sampleTest.ts'), true);\n    assert.strictEqual(Utils.isFileNameValid('/tests/sampleTest.json'), false);\n  });\n\n  it('readFolderRecursively with normal folder', async function(){\n    const absPath = [];\n    Utils.readFolderRecursively(path.join(__dirname, '../../extra/commands/other/'), [], (sourcePath, resource) => {\n      absPath.push(path.join(sourcePath, resource));\n    });\n    assert.deepStrictEqual(absPath, [path.join(__dirname, '../../extra/commands/other/otherCommand.js')]);\n  });\n\n  it('readFolderRecursively with glob pattern', async function(){\n    const absPath = [];\n    Utils.readFolderRecursively(path.join(__dirname, '../../extra/commands/typescript/*.js'), [], (sourcePath, resource) => {\n      absPath.push(path.join(sourcePath, resource));\n    });\n    assert.deepStrictEqual(absPath, [path.join(__dirname, '../../extra/commands/typescript/tsWait.js')]);\n  });\n\n  it('SafeJSON.stringify for circurlar reference objects', function() {\n    const obj = {\n      value: 1\n    };\n    obj.cirRef = obj;\n\n    assert.strictEqual(Utils.SafeJSON.stringify(obj), '{\"value\":1,\"cirRef\":\"[Circular]\"}');\n  });\n\n  it('SafeJSON.stringify for Proxy objects', function() {\n    \n    const target = {\n      value: 1\n    };\n\n    const proxyObj = new Proxy(target, {\n      get(target, property) {\n        return function(...args) {\n          if (!target[property]){\n            throw new Error('Unknown property');\n          }\n\n          return target[property];\n        };\n      }\n    });\n\n    assert.strictEqual(Utils.SafeJSON.stringify(proxyObj), '\"[Error]\"');\n  });\n\n  it('test printVersionInfo', function() {\n    const semVerRegex = /([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z-]+)?/;\n\n    const oldConsole = console;\n    const logArgs = [];\n\n    // eslint-disable-next-line no-console\n    console.log = function(args) {\n      logArgs.push(args);\n    };\n\n    Utils.printVersionInfo();\n    const logString = logArgs.join('\\n');\n    \n    assert.match(logString, /Nightwatch:/);\n    assert.match(logString, /version:/);\n    assert.match(logString, /changelog: https:\\/\\/github.com\\/nightwatchjs\\/nightwatch\\/releases\\/tag\\//);\n    assert.match(logString, semVerRegex);\n\n    // eslint-disable-next-line no-global-assign\n    console = oldConsole;\n  });\n\n  it('test getModuleKey', function() {\n    const srcFolderPath = path.join(__dirname, '../../sampletests/before-after');\n    const {statSync, readdirSync} = require('fs');\n    const getSrcTestsPaths = (testPath)=>{\n      let fullPaths = [];\n      readdirSync(testPath).forEach(file=>{\n        if (statSync(path.join(testPath, file)).isDirectory()){\n          fullPaths = [...fullPaths, ...getSrcTestsPaths(path.join(testPath, file))];\n        } else {\n          fullPaths.push(path.join(testPath, file));\n        }\n      });\n\n      return fullPaths;\n    };\n    const currentTestPath = path.join(srcFolderPath, 'sampleSingleTest.js');\n    const testFiles = getSrcTestsPaths(srcFolderPath);\n    const fullPaths = testFiles.map(file=>({env: 'default', module: file}));\n    assert.equal(Utils.getModuleKey(currentTestPath, testFiles, fullPaths), 'sampleSingleTest.js');\n    assert.equal(Utils.getModuleKey(currentTestPath, ['test/sampletests/simple', 'test/sampletests/before-after'], fullPaths), path.join('before-after', 'sampleSingleTest.js'));\n  });\n\n\n  describe('test findTSConfigFile', function () {\n    const {constants, rmdirSync} = require('fs');\n\n    beforeEach(function () {\n      mockery.enable({useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false});\n    });\n\n    afterEach(function () {\n      mockery.deregisterAll();\n      mockery.resetCache();\n      mockery.disable();\n    });\n\n    it('loads default tsconfig correctly', function () {\n      const tsConfigPath = path.join(__dirname, '../../typescript-tests/tsconfig.nightwatch.json');\n\n      const tsConfigFile = Utils.findTSConfigFile(tsConfigPath);\n\n      assert.strictEqual(tsConfigFile, tsConfigPath);\n    });\n\n    it('loads `tsconfig.nightwatch.json` correctly', function () {\n      mockery.registerMock('path', {\n        join: function (a, b) {\n          if (b === 'tsconfig.nightwatch.json') {\n            return '/path/to/tsconfig.nightwatch.json';\n          }\n        }\n      });\n      mockery.registerMock('fs', {\n        statSync: function (module) {\n          if (module === '/path/to/tsconfig.nightwatch.json') {\n            return {\n              isFile: function () {\n                return true;\n              }\n            };\n          }\n          throw new Error('Does not exist');\n        },\n        constants,\n        rmdirSync\n      });\n\n      const tsConfigPath = '/path/to/tsconfig.nightwatch.json';\n      const localUtils = common.require('utils');\n\n      const tsConfigFile = localUtils.findTSConfigFile('');\n\n      assert.strictEqual(tsConfigFile, tsConfigPath);\n    });\n\n    it('loads `nightwatch/tsconfig.json` correctly', function () {\n      mockery.registerMock('path', {\n        join: function (a, b) {\n          if (b === 'nightwatch') {\n            return '/path/to/nightwatch/tsconfig.json';\n          }\n        }\n      });\n      mockery.registerMock('fs', {\n        statSync: function (module) {\n          if (module === '/path/to/nightwatch/tsconfig.json') {\n            return {\n              isFile: function () {\n                return true;\n              }\n            };\n          }\n          throw new Error('Does not exist');\n        },\n        constants,\n        rmdirSync\n      });\n      const tsConfigPath = '/path/to/nightwatch/tsconfig.json';\n      const localUtils = common.require('utils');\n\n      const tsConfigFile = localUtils.findTSConfigFile('');\n\n      assert.strictEqual(tsConfigFile, tsConfigPath);\n    });\n  });\n});\n"
  },
  {
    "path": "test/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"esnext\",\n    /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */\n    \"module\": \"node16\",\n    /* Specify what module code is generated. */\n    \"allowJs\": true,\n    /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */\n    \"outDir\": \"dist\",\n    /* Specify an output folder for all emitted files. */\n    \"esModuleInterop\": true,\n    /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */\n    \"forceConsistentCasingInFileNames\": true,\n    /* Ensure that casing is correct in imports. */\n    \"strict\": true,\n    /* Enable all strict type-checking options. */\n    \"noImplicitAny\": true,\n    /* Enable error reporting for expressions and declarations with an implied 'any' type. */\n    \"skipLibCheck\": true\n    /* Skip type checking all .d.ts files. */\n  },\n  \"include\": [\n    \".\"\n  ],\n  \"files\": [\n    \"./types/index.d.ts\"\n  ]\n}"
  },
  {
    "path": "test/typescript-tests/demo.ts",
    "content": "import { NightwatchTests } from 'nightwatch';\nimport assert from 'assert';\n\nconst home: NightwatchTests = {\n  'Demo test': () => {\n    assert.strictEqual(1+1, 2);\n  }\n};\n\nexport default home;\n"
  },
  {
    "path": "test/typescript-tests/tsconfig.nightwatch.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"esnext\",\n    \"module\": \"commonjs\",\n    \"strict\": true,\n    \"rootDir\": \".\",\n    \"outDir\": \"dist\",\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": false,\n    \"resolveJsonModule\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noImplicitAny\": true,\n    \"noImplicitThis\": true,\n    \"strictNullChecks\": true,\n    \"skipLibCheck\": true\n  }\n}\n"
  },
  {
    "path": "types/assertions.d.ts",
    "content": "import {NightwatchCustomAssertions} from './custom-assertion';\nimport {Awaitable, Definition, ElementResult, JSON_WEB_OBJECT, ScopedSelector} from './index';\nimport { IfUnknown } from './utils';\n\nexport interface NightwatchAssertionsError {\n\tname: string;\n\tmessage: string;\n\tshowDiff: boolean;\n\tstack: string;\n}\n\nexport interface NightwatchCommonAssertions<ReturnType> {\n\t/**\n\t * Checks if the given attribute of an element contains the expected value.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.attributeContains('#someElement', 'href', 'google.com');\n\t *    };\n\t * ```\n\t */\n\tattributeContains(\n\t\tselector: Definition,\n\t\tattribute: string,\n\t\texpected: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the given attribute of an element has the expected value.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.attributeEquals('body', 'data-attr', 'some value');\n\t *    };\n\t * ```\n\t */\n\tattributeEquals(\n\t\tselector: Definition,\n\t\tattribute: string,\n\t\texpected: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Check if an element's attribute value matches a regular expression.\n\t *\n\t * @example\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.attributeMatches('body', 'data-attr', '(value)');\n\t *    };\n\t * ```\n\t *\n\t */\n\tattributeMatches(\n\t\tselector: Definition,\n\t\tattribute: string,\n\t\tregex: string | RegExp,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the specified css property of a given element has the expected value.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.cssProperty('#main', 'display', 'block');\n\t *    };\n\t * ```\n\t */\n\tcssProperty(\n\t\tselector: Definition,\n\t\tcssProperty: string,\n\t\texpected: string,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the specified DOM property of a given element has the expected value.\n\t * For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n\t * Several properties can be specified (either as an array or command-separated list). Nightwatch will check each one for presence.\n\t */\n\tdomPropertyContains(\n\t\tselector: Definition,\n\t\tdomProperty: string,\n\t\texpected: string | number,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<any>>;\n\n\t/**\n\t * Checks if the specified DOM property of a given element has the expected value.\n\t * For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n\t * If the result value is JSON object or array, a deep equality comparison will be performed.\n\t */\n\tdomPropertyEquals(\n\t\tselector: Definition,\n\t\tdomProperty: string,\n\t\texpected: string | number,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<any>>;\n\n\t/**\n\t * Check if specified DOM property value of a given element matches a regex.\n\t * For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n\t */\n\tdomPropertyMatches(\n\t\tselector: Definition,\n\t\tdomProperty: string,\n\t\texpected: string | RegExp,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<any>>;\n\n\t/**\n\t * Checks if the number of elements specified by a selector is equal to a given value.\n\t *\n\t * @example\n\t *\n\t * this.demoTest = function (browser) {\n\t *   browser.assert.elementsCount('div', 10);\n\t *   browser.assert.not.elementsCount('div', 10);\n\t * }\n\t *\n\t */\n\telementsCount(\n\t\tselector: ScopedSelector,\n\t\tcount: number,\n\t\tmsg?: string\n\t): Awaitable<\n\t\tIfUnknown<ReturnType, this>,\n\t\tNightwatchAssertionsResult<JSON_WEB_OBJECT[]> & {\n\t\t\tWebdriverElementId: string;\n\t\t}\n\t>;\n\n\t/**\n\t * Checks if the given element exists in the DOM.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.elementPresent(\"#main\");\n\t *    };\n\t * ```\n\t */\n\telementPresent(\n\t\tselector: ScopedSelector,\n\t\tmsg?: string\n\t): Awaitable<\n\t\tIfUnknown<ReturnType, this>,\n\t\tNightwatchAssertionsResult<ElementResult[]>\n\t>;\n\n\t/**\n\t * Checks if the given element does not exists in the DOM.\n\t *\n\t * @example\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.elementNotPresent(\".should_not_exist\");\n\t *    };\n\t * ```\n\t *\n\t * @deprecated In favour of `assert.not.elementPresent()`.\n\t */\n\telementNotPresent(\n\t\tselector: Definition,\n\t\tmsg?: string\n\t): Awaitable<\n\t\tIfUnknown<ReturnType, this>,\n\t\tNightwatchAssertionsResult<ElementResult[]>\n\t>;\n\n\t/**\n\t * Checks if the given element does not have the specified CSS class.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.cssClassNotPresent('#main', 'container');\n\t *    };\n\t * ```\n\t *\n\t * @deprecated In favour of `assert.not.hasClass()`.\n\t */\n\tcssClassNotPresent(\n\t\tselector: Definition,\n\t\tclassName: string,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the given element has the specified CSS class.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.cssClassPresent('#main', 'container');\n\t *    };\n\t * ```\n\t *\n\t * @deprecated In favour of `assert.hasClass()`.\n\t */\n\tcssClassPresent(\n\t\tselector: Definition,\n\t\tclassName: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the given element has the specified CSS class.\n\t *\n\t * @example\n\t *\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.hasClass('#main', 'container');\n\t *      browser.assert.hasClass('#main', ['visible', 'container']);\n\t *      browser.assert.hasClass('#main', 'visible container');\n\t *    };\n\t * ```\n\t *\n\t */\n\thasClass(\n\t\tselector: Definition,\n\t\tclassName: string | string[],\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the given element contains the specified DOM attribute.\n\t *\n\t * Equivalent of: https://developer.mozilla.org/en-US/docs/Web/API/Element/hasAttribute\n\t *\n\t * @example\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.hasAttribute('#main', 'data-track');\n\t *    };\n\t * ```\n\t *\n\t */\n\thasAttribute(\n\t\tselector: Definition,\n\t\texpectedAttribute: string,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the given element is enabled (as indicated by the 'disabled' attribute).\n\t *\n\t * @example\n\t *  this.demoTest = function (browser) {\n\t *    browser.assert.enabled('.should_be_enabled');\n\t *    browser.assert.enabled({selector: '.should_be_enabled'});\n\t *    browser.assert.enabled({selector: '.should_be_enabled', suppressNotFoundErrors: true});\n\t *  };\n\t */\n\tenabled(\n\t\tselector: Definition,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<boolean>>;\n\n\t/**\n\t * Checks if the given element is selected.\n\t *\n\t * @example\n\t *  this.demoTest = function (browser) {\n\t *    browser.assert.selected('.should_be_selected');\n\t *    browser.assert.selected({selector: '.should_be_selected'});\n\t *    browser.assert.selected({selector: '.should_be_selected', suppressNotFoundErrors: true});\n\t *  };\n\t */\n\tselected(\n\t\tselector: Definition,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<boolean>>;\n\n\t/**\n\t * Checks if the given element contains the specified text.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.containsText('#main', 'The Night Watch');\n\t *    };\n\t * ```\n\t *\n\t * @deprecated In favour of `assert.textContains()`.\n\t */\n\tcontainsText(\n\t\tselector: Definition,\n\t\texpectedText: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the given element contains the specified text.\n\t *\n\t * @example\n\t * ```\n\t *   this.demoTest = function (browser) {\n\t *     browser.assert.textContains('#main', 'The Night Watch');\n\t *   };\n\t * ```\n\t *\n\t */\n\ttextContains(\n\t\tselector: Definition,\n\t\texpectedText: string,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Check if an element's inner text equals the expected text.\n\t *\n\t * @example\n\t *\n\t * ```\n\t *   this.demoTest = function (browser) {\n\t *     browser.assert.textEquals('#main', 'The Night Watch');\n\t *   };\n\t * ```\n\t *\n\t */\n\ttextEquals(\n\t\tselector: Definition,\n\t\texpectedText: string,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Check if an elements inner text matches a regular expression.\n\t *\n\t * @example\n\t *\n\t * ```\n\t *   this.demoTest = function (browser) {\n\t *     browser.assert.textMatches('#main', '^Nightwatch');\n\t *   };\n\t * ```\n\t *\n\t */\n\ttextMatches(\n\t\tselector: Definition,\n\t\tregex: string | RegExp,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the page title equals the given value.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.title(\"Nightwatch.js\");\n\t *    };\n\t * ```\n\t *\n\t * @deprecated In favour of `titleEquals()`.\n\t */\n\ttitle(\n\t\texpected: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the page title equals the given value.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.title(\"Nightwatch.js\");\n\t *    };\n\t * ```\n\t */\n\ttitleContains(\n\t\texpected: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the page title equals the given value.\n\t * @since 2.0\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.titleEquals(\"Nightwatch.js\");\n\t *    };\n\t * ```\n\t */\n\ttitleEquals(\n\t\texpected: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the current title matches a regular expression.\n\t *\n\t * @example\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.titleMatches('^Nightwatch');\n\t *    };\n\t * ```\n\t *\n\t */\n\ttitleMatches(\n\t\tregex: string | RegExp,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the current URL contains the given value.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.urlContains('google');\n\t *    };\n\t * ```\n\t */\n\turlContains(\n\t\texpectedText: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the current url equals the given value.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.urlEquals('https://www.google.com');\n\t *    };\n\t * ```\n\t */\n\turlEquals(\n\t\texpected: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the current url matches a regular expression.\n\t *\n\t * @example\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.urlMatches('^https');\n\t *    };\n\t * ```\n\t *\n\t */\n\turlMatches(\n\t\tregex: string | RegExp,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the given form element's value equals the expected value.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.value(\"form.login input[type=text]\", \"username\");\n\t *    };\n\t * ```\n\t *\n\t * @deprecated In favour of `assert.valueEquals()`.\n\t */\n\tvalue(\n\t\tselector: Definition,\n\t\texpectedText: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the given form element's value contains the expected value.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.valueContains(\"form.login input[type=text]\", \"username\");\n\t *    };\n\t * ```\n\t */\n\tvalueContains(\n\t\tselector: Definition,\n\t\texpectedText: string,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the given form element's value equals the expected value.\n\t *\n\t * The existing .assert.value() command.\n\t *\n\t * @example\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.valueEquals(\"form.login input[type=text]\", \"username\");\n\t *    };\n\t * ```\n\t *\n\t */\n\tvalueEquals(\n\t\tselector: Definition,\n\t\texpected: string,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<string>>;\n\n\t/**\n\t * Checks if the given element is not visible on the page.\n\t *\n\t * @example\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.hidden('.should_not_be_visible');\n\t *    };\n\t * ```\n\t *\n\t * @deprecated In favour of `assert.not.visible()`.\n\t */\n\thidden(\n\t\tselector: Definition,\n\t\tmsg?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<boolean>>;\n\n\t/**\n\t * Checks if the given element is visible on the page.\n\t *\n\t * ```\n\t *    this.demoTest = function (browser) {\n\t *      browser.assert.visible(\".should_be_visible\");\n\t *    };\n\t * ```\n\t */\n\tvisible(\n\t\tselector: Definition,\n\t\tmessage?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchAssertionsResult<boolean>>;\n\n\tNightwatchAssertionsError: NightwatchAssertionsError;\n}\n\nexport interface NightwatchNodeAssertionsResult {\n\tvalue: null;\n\treturned: 1;\n}\n\nexport interface NightwatchNodeAssertions<ReturnType> {\n\t// The following definitions are taken from @types/assert\n\n\tfail(\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\tfail(\n\t\tactual: any,\n\t\texpected: any,\n\t\tmessage?: string | Error,\n\t\toperator?: string\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\n\tok(\n\t\tvalue: any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\n\tequal(\n\t\tactual: any,\n\t\texpected: any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\tnotEqual(\n\t\tactual: any,\n\t\texpected: any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\n\tdeepEqual(\n\t\tactual: any,\n\t\texpected: any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\tnotDeepEqual(\n\t\tactual: any,\n\t\texpected: any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\n\tstrictEqual(\n\t\tactual: any,\n\t\texpected: any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\tnotStrictEqual(\n\t\tactual: any,\n\t\texpected: any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\n\tdeepStrictEqual(\n\t\tactual: any,\n\t\texpected: any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\tnotDeepStrictEqual(\n\t\tactual: any,\n\t\texpected: any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\n\tthrows(\n\t\tblock: () => any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\tdoesNotThrow(\n\t\tblock: () => any,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\n\tifError(\n\t\tvalue: any\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\n\trejects(\n\t\tblock: (() => Promise<any>) | Promise<any>,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\tdoesNotReject(\n\t\tblock: (() => Promise<any>) | Promise<any>,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\n\tmatch(\n\t\tvalue: string,\n\t\tregExp: RegExp,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n\tdoesNotMatch(\n\t\tvalue: string,\n\t\tregExp: RegExp,\n\t\tmessage?: string | Error\n\t): Awaitable<IfUnknown<ReturnType, this>, NightwatchNodeAssertionsResult | Error>;\n}\n\nexport interface NightwatchAssertions<ReturnType>\n\textends NightwatchCommonAssertions<ReturnType>,\n\tNightwatchCustomAssertions<ReturnType> {\n\t/**\n\t * Negates any of assertions following in the chain.\n\t */\n\tnot: Omit<NightwatchAssertions<ReturnType>, 'not'>;\n}\n\nexport interface NightwatchAssertionsResult<T> {\n\tvalue: T;\n\tstatus: 0;\n\treturned: 1;\n\tpassed: true;\n}\n\nexport interface Assert<ReturnType = unknown>\n\textends NightwatchAssertions<ReturnType>,\n\tNightwatchNodeAssertions<ReturnType> { }\n\n// TODO: Check where the following type is being used.\n/**\n * Performs an assertion\n *\n */\nexport type NightwatchAssert = (\n\tpassed: boolean,\n\treceivedValue?: any,\n\texpectedValue?: any,\n\tmessage?: string,\n\tabortOnFailure?: boolean,\n\toriginalStackTrace?: string\n) => void;\n"
  },
  {
    "path": "types/chrome-options.d.ts",
    "content": "export interface ChromePerfLoggingPrefs {\n\t/**\n\t * Default: true. Whether or not to collect events from Network domain.\n\t */\n\tenableNetwork?: boolean | undefined;\n\n\t/**\n\t * Default: true. Whether or not to collect events from Page domain.\n\t */\n\tenablePage?: boolean | undefined;\n\n\t/**\n\t * A comma-separated string of Chrome tracing categories for which trace events should be collected.\n\t * An unspecified or empty string disables tracing.\n\t */\n\ttraceCategories?: string | undefined;\n\n\t/**\n\t * Default: 1000. The requested number of milliseconds between DevTools trace buffer usage events. For example, if 1000,\n\t * then once per second, DevTools will report how full the trace buffer is. If a report indicates the buffer usage is 100%,\n\t * a warning will be issued.\n\t */\n\tbufferUsageReportingInterval?: number | undefined;\n}\n\nexport interface ChromeOptions {\n\t/**\n\t * Whether to run Chromedriver using w3c protocol or the legacy JSONWire protocol.\n\t *\n\t * @deprecated Chromedriver now only supports w3c protocol.\n\t */\n\tw3c?: true;\n\n\t/**\n\t * List of command-line arguments to use when starting Chrome. Arguments with an associated value should be separated by a '=' sign\n\t * (e.g., ['start-maximized', 'user-data-dir=/tmp/temp_profile']).\n\t */\n\targs?: string[] | undefined;\n\n\t/**\n\t * Path to the Chrome executable to use (on Mac OS X, this should be the actual binary, not just the app. e.g.,\n\t * '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome')\n\t */\n\tbinary?: string | undefined;\n\n\t/**\n\t * A list of Chrome extensions to install on startup. Each item in the list should be a base-64 encoded packed Chrome extension (.crx)\n\t */\n\textensions?: string[] | undefined;\n\n\t/**\n\t * A dictionary with each entry consisting of the name of the preference and its value. These preferences are applied\n\t * to the Local State file in the user data folder.\n\t */\n\tlocalState?: Record<string, string> | undefined;\n\n\t/**\n\t * A dictionary with each entry consisting of the name of the preference and its value. These preferences are only applied\n\t * to the user profile in use.\n\t */\n\tprefs?: Record<string, string> | undefined;\n\n\t/**\n\t * Default: false. If false, Chrome will be quit when ChromeDriver is killed, regardless of whether the session is quit.\n\t * If true, Chrome will only be quit if the session is quit (or closed). Note, if true, and the session is not quit,\n\t * ChromeDriver cannot clean up the temporary user data directory that the running Chrome instance is using.\n\t */\n\tdetach?: boolean | undefined;\n\n\t/**\n\t * An address of a Chrome debugger server to connect to, in the form of <hostname/ip:port>, e.g. '127.0.0.1:38947'\n\t */\n\tdebuggerAddress?: string | undefined;\n\n\t/**\n\t * List of Chrome command line switches to exclude that ChromeDriver by default passes when starting Chrome.\n\t * Do not prefix switches with --.\n\t */\n\texcludeSwitches?: string[] | undefined;\n\n\t/**\n\t * Directory to store Chrome minidumps . (Supported only on Linux.)\n\t */\n\tminidumpPath?: string | undefined;\n\n\t/**\n\t * A dictionary with either a value for “deviceName,” or values for “deviceMetrics” and “userAgent.” Refer to Mobile Emulation for more information.\n\t */\n\tmobileEmulation?: Record<string, string> | undefined;\n\n\t/**\n\t * An optional dictionary that specifies performance logging preferences. See below for more information.\n\t */\n\tperfLoggingPrefs?: ChromePerfLoggingPrefs | undefined;\n\n\t/**\n\t * A list of window types that will appear in the list of window handles. For access to <webview> elements, include \"webview\" in this list.\n\t */\n\twindowTypes?: string[] | undefined;\n\n\t/**\n\t * Name of the Android package to do automation on. E.g., 'com.android.chrome'.\n\t */\n\tandroidPackage?: string;\n\n\t/**\n\t * Serial number of the device to connect to via ADB. If not specified, the\n\t * WebDriver server will select an unused device at random. An error will be\n\t * returned if all devices already have active sessions.\n\t */\n\tandroidDeviceSerial?: string;\n}\n"
  },
  {
    "path": "types/custom-assertion.d.ts",
    "content": "import {NightwatchAPI, NightwatchClientObject} from './index';\n\ninterface NightwatchAssertionSuccessfulResult<T> {\n  value?: T;\n}\n\ninterface NightwatchAssertionFailedResult<T> {\n  value: T;\n  status: number;\n}\n\n/**\n * @example\n * import {ScopedSelector, NightwatchAssertion} from 'nightwatch';\n *\n * export const assertion = function ElementHasCount(this: NightwatchAssertion<number>, selector: ScopedSelector, count: number) {\n *   this.message = `Testing if element <${selector}> has count: ${count}`;   \n *\n *   this.expected = count;\n *\n *   this.value = (result) => {\n *     return result.value;\n *   }\n *\n *   this.evaluate = (value) => {\n *     return value === count;\n *   }\n *\n *   this.command = async (callback) => {\n *     const elementsCount = await this.api.element.findAll(selector).count();\n *     callback({value: elementsCount});\n *   }\n * }\n *\n * @see https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html\n */\nexport interface NightwatchAssertion<T> {\n  /**\n   * If the custom commands operates with DOM elements, this options should be set\n   */\n  options?: {\n    elementSelector: boolean;\n  };\n\n  /**\n   * Returns the expected value of the assertion which is displayed in the case of a failure\n   *\n   * @internal\n   *\n   * @example\n   * this.expected = function() {\n   *   return this.negate ? `is not '${expectedText}'` : `is '${expectedText}'`;\n   * };\n   *\n   */\n  expected: (() => T) | T;\n\n  /**\n   * The message which will be used in the test output ana inside the XML reports\n   *\n   * @remarks The formatMessage method creates the same option message. this.message or this.formatMessage must be specified!\n   *\n   * @internal\n   *\n   * @example\n   * this.message = `Testing if the page title contains ${expression}`;\n   */\n  message?: string;\n\n  /**\n   * The method which performs the actual assertion.\n   * It is called with the result of the value method as the argument.\n   *\n   * This option can also override the evaluate method. this.pass or this.evaluate must be specified.\n   */\n  pass?(value: T): unknown;\n\n  /**\n   * Called with the result object of the command to retrieve the value which is to be evaluated\n   */\n  value?(result: NightwatchAssertionSuccessfulResult<T>): T;\n\n  /**\n   * The command which is to be executed by the assertion runner; Nightwatch api is available as this.api\n   */\n  command(\n    this: Pick<NightwatchAssertion<T>, 'client' | 'api' | 'negate'>,\n    callback: (result: NightwatchAssertionSuccessfulResult<T>) => void\n  ): unknown;\n\n  /**\n   * Returns the message format which will be used to output the message in the console and also\n   * the arguments which will be used for replace the placeholders, used in the order of appearance.\n   *\n   * The message format also takes into account whether the .not negate has been used.\n   *\n   * The formatMessage method creates option message. this.message or this.formatMessage must be specified.\n   *\n   * @internal\n   *\n   * @example\n   * this.formatMessage = function() {\n   *   // Use this.negate to determine if \".not\" is in use\n   *   // Example:\n   *   const message = `Testing if the page title ${this.negate ? 'doesn\\'t equal %s' : 'equals %s'}`;\n   *\n   *   return {\n   *     message,\n   *     args: [`'${expected}'`]\n   *   }\n   * };\n   */\n  formatMessage?(): { message: string; args: unknown[] };\n\n  /**\n   * Given the value, the condition used to evaluate if the assertion is passed\n   *\n   * @remarks This option can also override the pass method. this.pass or this.evaluate must be specified!   *\n   */\n  evaluate?(value: T): boolean;\n\n  /**\n   * When defined, this method is called by the assertion runner with the command result, to determine if the\n   * value can be retrieved successfully from the result object\n   */\n  failure?(result: NightwatchAssertionFailedResult<T>): boolean;\n\n  /**\n   * When defined, this method is called by the assertion runner with the command result to determine the actual\n   * state of the assertion in the event of a failure\n   */\n  actual?(passed: boolean): string;\n\n  /**\n   * Nightwatch API\n   */\n  readonly api: NightwatchAPI;\n\n  /**\n   * Nightwatch Client\n   */\n  readonly client: NightwatchClientObject;\n\n  /**\n   * Use this.negate to determine if \".not\" is in use\n   */\n  readonly negate: boolean;\n}\n\n/**\n * @see https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html\n */\nexport interface NightwatchCustomAssertions<ReturnType> {}\n"
  },
  {
    "path": "types/custom-command.d.ts",
    "content": "import {CommandInstance} from './index';\n\nexport interface CustomCommandInstance extends CommandInstance {}\n\nexport interface NightwatchCustomCommandsModel {\n  /**\n   * Define a custom command\n   *\n   * @example\n   * class LogMessage implements NightwatchCustomCommandsModel {\n   *   command() {\n   *\n   *     return Promise.resolve();\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html#define-a-custom-command\n   */\n  command: (...args: any[]) => unknown | Promise<unknown>;\n}\n\n/**\n * @see https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html#define-a-custom-command\n */\nexport interface NightwatchCustomCommands {}\n"
  },
  {
    "path": "types/desired-capabilities.d.ts",
    "content": "import {ChromeOptions} from \"./chrome-options\";\n\n//  TODO: visit later (some settings here are no longer used)\nexport interface NightwatchDesiredCapabilities {\n\t[key: `${string}:${string}`]: unknown;\n\n\t/**\n\t * The name of the browser being used; examples: {chrome|firefox|safari|edge|internet explorer|opera|brave|null}.\n\t */\n\tbrowserName?: string | null;\n\n\t/**\n\t * The browser version, or the empty string if unknown.\n\t */\n\tbrowserVersion?: string;\n\n\t/**\n\t * A key specifying which platform the browser should be running on. This value should be one of {WINDOWS|XP|VISTA|MAC|LINUX|UNIX|ANDROID|IOS}.\n\t * When requesting a new session, the client may specify ANY to indicate any available platform may be used.\n\t * For more information see [GridPlatforms (https://code.google.com/p/selenium/wiki/GridPlatforms)]\n\t */\n\tplatformName?: string;\n\n\t/**\n\t * Indicates whether untrusted and self-signed TLS certificates are implicitly trusted on navigation for the duration of the session.\n\t */\n\tacceptInsecureCerts?: boolean;\n\n\t/**\n\t * Whether the session supports taking screenshots of the current page.\n\t */\n\ttakesScreenShot?: boolean | undefined;\n\n\t/**\n\t * Whether the session can interact with modal popups, such as window.alert and window.confirm.\n\t */\n\thandlesAlerts?: boolean | undefined;\n\n\t/**\n\t * Whether the session supports CSS selectors when searching for elements.\n\t */\n\tcssSelectorsEnabled?: boolean | undefined;\n\n\t/**\n\t * Whether the session supports executing user supplied JavaScript in the context of the current page (only on HTMLUnitDriver).\n\t */\n\tjavascriptEnabled?: boolean | undefined;\n\n\t/**\n\t * Whether the session can interact with database storage.\n\t */\n\tdatabaseEnabled?: boolean | undefined;\n\n\t/**\n\t * Whether the session can set and query the browser's location context.\n\t */\n\tlocationContextEnabled?: boolean | undefined;\n\n\t/**\n\t * Whether the session can interact with the application cache.\n\t */\n\tapplicationCacheEnabled?: boolean | undefined;\n\n\t/**\n\t * Whether the session can query for the browser's connectivity and disable it if desired.\n\t */\n\tbrowserConnectionEnabled?: boolean | undefined;\n\n\t/**\n\t * Whether the session supports interactions with storage objects (http://www.w3.org/TR/2009/WD-webstorage-20091029/).\n\t */\n\twebStorageEnabled?: boolean | undefined;\n\n\t/**\n\t * Whether the session should accept all SSL certs by default.\n\t */\n\tacceptSslCerts?: boolean | undefined;\n\n\t/**\n\t * Whether the session can rotate the current page's current layout between portrait and landscape orientations (only applies to mobile platforms).\n\t */\n\trotatable?: boolean | undefined;\n\n\t/**\n\t * Whether the session is capable of generating native events when simulating user input.\n\t */\n\tnativeEvents?: boolean | undefined;\n\n\t/**\n\t * What the browser should do with an unhandled alert before throwing out the UnhandledAlertException. Possible values are \"accept\", \"dismiss\" and \"ignore\"\n\t */\n\tunexpectedAlertBehaviour?: string | undefined;\n\n\t/**\n\t * Allows the user to specify whether elements are scrolled into the viewport for interaction to align with the top (0) or bottom (1) of the viewport.\n\t * The default value is to align with the top of the viewport. Supported in IE and Firefox (since 2.36)\n\t */\n\telementScrollBehaviour?: number | undefined;\n\n\t/**\n\t * A JSON object describing the logging level of different components in the browser, the driver, or any intermediary WebDriver servers.\n\t * Available values for most loggers are \"OFF\", \"SEVERE\", \"WARNING\", \"INFO\", \"CONFIG\", \"FINE\", \"FINER\", \"FINEST\", \"ALL\".\n\t * This produces a JSON object looking something like: {\"loggingPrefs\": {\"driver\": \"INFO\", \"server\": \"OFF\", \"browser\": \"FINE\"}}.\n\t */\n\t'goog:loggingPrefs'?: {\n\t\tbrowser?: string | undefined;\n\t\tdriver?: string | undefined;\n\t\tserver?: string | undefined;\n\t};\n\n\t/**\n\t * List all the Chrome-specific desired capabilities.\n\t * @deprecated In favour of `goog:chromeOptions`.\n\t */\n\tchromeOptions?: ChromeOptions;\n\n\t/**\n\t * List all the Chrome-specific desired capabilities.\n\t */\n\t'goog:chromeOptions'?: ChromeOptions;\n}\n"
  },
  {
    "path": "types/expect.d.ts",
    "content": "import { By, WebElement } from 'selenium-webdriver';\nimport {Definition, NightwatchAPI, Awaitable, Element, ELEMENT_KEY, ScopedSelector} from './index';\n\nexport interface NightwatchExpectResult {\n  value: null;\n  returned: 1;\n}\n\nexport interface ExpectLanguageChains<T> {\n  // The following are provided as chainable getters\n  // to improve the readability of your assertions.\n  // They do not provide testing capabilities and\n  // the order is not important.\n  to: T;\n  be: T;\n  been: T;\n  is: T;\n  that: T;\n  which: T;\n  and: T;\n  has: T;\n  have: T;\n  with: T;\n  at: T;\n  does: T;\n  of: T;\n  same: T;\n\n  /**\n   * Negates any of assertions following in the chain.\n   */\n  not: T;\n\n  /**\n   * Sets the `deep` flag, later to be used by the `equal`.\n   */\n  deep: T;\n}\n\nexport interface ExpectEqual<T> {\n  (value: any): Awaitable<T, NightwatchExpectResult>;\n}\n\nexport interface ExpectInclude<T> {\n  (value: string): Awaitable<T, NightwatchExpectResult>;\n}\n\nexport interface ExpectMatch<T> {\n  (regexp: RegExp): Awaitable<T, NightwatchExpectResult>;\n}\n\nexport interface ExpectStartWith<T> {\n  (value: string): Awaitable<T, NightwatchExpectResult>;\n}\n\nexport interface ExpectEndWith<T> {\n  (value: string): Awaitable<T, NightwatchExpectResult>;\n}\n\nexport interface ExpectAssertions<T> extends ExpectLanguageChains<T> {\n  equal: ExpectEqual<T>;\n  equals: ExpectEqual<T>;\n  eq: ExpectEqual<T>;\n\n  include: ExpectInclude<T>;\n  includes: ExpectInclude<T>;\n  contain: ExpectInclude<T>;\n  contains: ExpectInclude<T>;\n\n  match: ExpectMatch<T>;\n  matches: ExpectMatch<T>;\n\n  startWith: ExpectStartWith<T>;\n  startsWith: ExpectStartWith<T>;\n\n  endWith: ExpectEndWith<T>;\n  endsWith: ExpectEndWith<T>;\n\n  before: (ms: number) => Awaitable<T, NightwatchExpectResult>;\n  after: (ms: number) => Awaitable<T, NightwatchExpectResult>;\n\n  // Assertion methods returning NightwatchAPI\n  toEqual: (value: any) => NightwatchAPI;\n  toBe: (value: any) => NightwatchAPI;\n  toContain: (value: string) => NightwatchAPI;\n  toMatch: (regexp: RegExp) => NightwatchAPI;\n  toEndWith: (value: string) => NightwatchAPI;\n}\n\nexport interface ExpectCookie extends ExpectAssertions<ExpectCookie> {}\n\nexport interface ExpectElement extends ExpectAssertions<ExpectElement> {\n  /**\n   * Checks if the type (i.e. tag name) of a specified element is of an expected value.\n   */\n  a(type: string, message?: string): Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Checks if the type (i.e. tag name) of a specified element is of an expected value.\n   */\n  an(type: string, message?: string): Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Property that checks if an element is active in the DOM.\n   */\n  active: Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Checks if a given attribute of an element exists and optionally if it has the expected value.\n   */\n  attribute(\n    attribute: string,\n    message?: string\n  ): Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Checks a given css property of an element exists and optionally if it has the expected value.\n   */\n  css(\n    property: string,\n    message?: string\n  ): Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Property that checks if an element is currently enabled.\n   */\n  enabled: Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Property that checks if an element is present in the DOM.\n   */\n  present: Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Checks if a given DOM property of an element has the expected value.\n   * For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n   */\n  property(\n    name: string,\n    message?: string\n  ): Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Property that checks if an OPTION element, or an INPUT element of type checkbox or radio button is currently selected.\n   */\n  selected: Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Property that retrieves the text contained by an element. Can be chained to check if contains/equals/matches the specified text or regex.\n   */\n  text: Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Property that retrieves the value (i.e. the value attributed) of an element. Can be chained to check if contains/equals/matches the specified text or regex.\n   */\n  value: Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Property that asserts the visibility of a specified element.\n   */\n  visible: Awaitable<this, NightwatchExpectResult>;\n\n  /**\n   * Checks if the specified DOM property of a given element is present and has the expected value.\n   * For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n   */\n  domProperty(\n    propertyName: string,\n    message?: string\n  ): Awaitable<this, NightwatchExpectResult>;\n}\n\nexport interface ExpectSection extends ExpectAssertions<ExpectSection>, ExpectElement {}\n\nexport interface ExpectElements extends ExpectAssertions<ExpectElements> {\n  /**\n   * Checks if the number of elements specified by a selector is equal or not to a given value.\n   */\n  count: this;\n}\n\nexport interface ExpectTitle extends ExpectAssertions<ExpectTitle> {}\n\nexport interface ExpectUrl extends ExpectAssertions<ExpectUrl> {}\n\nexport interface Expect {\n  (val: Element | WebElement | By | {[ELEMENT_KEY]: string}): ExpectElement;\n  (val: any): Chai.Assertion;\n\n  /**\n   *  Expect assertions operating on a single cookie after\n   *  retrieving the entire cookie string, using .getCookies().\n   */\n  cookie(name: string, domain?: string): ExpectCookie;\n\n  /**\n   * Expect assertions operating on a single element, specified by its CSS/Xpath selector.\n   */\n  element(property: Definition): ExpectElement;\n\n  /**\n   * Expect assertions operating on a single component.\n   */\n  component(property: Definition): ExpectElement;\n\n  /**\n   * Expect assertions operating on a page-object section, specified by '`@section_name`'.\n   */\n  section(property: ScopedSelector): ExpectSection;\n\n  /**\n   * Expect assertions operating on a collection of elements, specified by a CSS/Xpath selector.\n   * So far only .count is available.\n   */\n  elements(property: ScopedSelector): ExpectElements;\n\n  /**\n   * Retrieves the page title value in order to be used for performing equal, match or contains assertions on it.\n   */\n  title(): ExpectTitle;\n\n  /**\n   * Retrieves the page url value in order to be used for performing equal, match or contains assertions on it.\n   */\n  url(): ExpectUrl;\n}\n"
  },
  {
    "path": "types/globals.d.ts",
    "content": "import { NightwatchAPI } from './index';\n\n/**\n * @see https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals\n */\nexport interface NightwatchGlobals extends NightwatchInternalGlobals {\n  /**\n   * Custom Globals properties\n   *\n   * @example\n   * myGlobalVar: \"some value\"\n   */\n  [key: string]: any;\n}\n\nexport interface NightwatchInternalGlobals {\n  /**\n   * This controls whether to abort the test execution when an assertion failed and skip the rest\n   * it's being used in waitFor commands and expect assertions\n   *\n   * @default true\n   *\n   * @example\n   * abortOnAssertionFailure: true\n   */\n  abortOnAssertionFailure?: boolean;\n\n  /**\n   * This will overwrite the default polling interval (currently 500ms) for waitFor commands\n   * and expect assertions that use retry\n   *\n   * @default 500\n   *\n   * @example\n   * waitForConditionPollInterval: 500\n   */\n  waitForConditionPollInterval?: number;\n\n  /**\n   * Default timeout value in milliseconds for waitFor commands and implicit waitFor value for\n   * expect assertions\n   *\n   * @default 5000\n   *\n   * @example\n   * waitForConditionTimeout: 5000\n   */\n  waitForConditionTimeout?: number;\n\n  /**\n   * Since 1.4.0 – this controls whether to abort the test execution when an element cannot be located; an error\n   * is logged in all cases, but this also enables skipping the rest of the testcase;\n   * it's being used in element commands such as .click() or .getText()\n   *\n   * @default false\n   *\n   * @example\n   * abortOnElementLocateError: false\n   */\n  abortOnElementLocateError?: boolean;\n\n  /**\n   * This will cause waitFor commands on elements to throw an error if multiple\n   * elements are found using the given locate strategy and selector\n   *\n   * @default false\n   *\n   * @example\n   * throwOnMultipleElementsReturned: false\n   */\n  throwOnMultipleElementsReturned?: boolean;\n\n  /**\n   * By default a warning is printed if multiple elements are found using the given locate strategy\n   * and selector; set this to true to suppress those warnings\n   *\n   * @default false\n   *\n   * @example\n   * suppressWarningsOnMultipleElementsReturned: false\n   */\n  suppressWarningsOnMultipleElementsReturned?: boolean;\n\n  /**\n   * Controls the timeout value for async hooks. Expects the done() callback to be invoked within this time\n   * or an error is thrown\n   *\n   * @default 10000\n   *\n   * @example\n   * asyncHookTimeout: 10000\n   */\n  asyncHookTimeout?: number;\n\n  /**\n   * Controls the timeout value for when running async unit tests. Expects the done() callback to be invoked within this time\n   * or an error is thrown\n   *\n   * @default 2000\n   *\n   * @example\n   * unitTestsTimeout: 2000\n   */\n  unitTestsTimeout?: number;\n\n  /**\n   * Controls the timeout value for when executing the global async reporter. Expects the done() callback to be\n   * invoked within this time or an error is thrown\n   *\n   * @default 20000\n   *\n   * @example\n   * customReporterCallbackTimeout: 20000\n   */\n  customReporterCallbackTimeout?: number;\n\n  /**\n   * Automatically retrying failed assertions - You can tell Nightwatch to automatically retry failed assertions\n   * until a given timeout is reached, before the test runner gives up and fails the test.\n   *\n   * @default 5000\n   *\n   * @example\n   * retryAssertionTimeout: 5000\n   */\n  retryAssertionTimeout?: number;\n\n  /**\n   * Use the same browser session to run the individual test suites\n   *\n   * @default false\n   *\n   * @example\n   * reuseBrowserSession: false\n   */\n  reuseBrowserSession?: boolean;\n\n  /**\n   * Custom reporter\n   *\n   * @example\n   *  reporter: function(results, done) {\n   *    // do something with the results\n   *    done(results);\n   *  }\n   */\n  reporter?(results: unknown, done: (...args: unknown[]) => void): void;\n\n  /**\n   * External before hook is ran at the beginning of the tests run, before creating the Selenium session\n   *\n   * @example\n   * before(done) {\n   *   done();\n   * }\n   */\n  before?(done: (err?: unknown) => void): void;\n\n  /**\n   * External after hook is ran at the very end of the tests run, after closing the Selenium session\n   *\n   * @example\n   * after(done) {\n   *   done();\n   * }\n   */\n  after?(done: (err?: unknown) => void): void;\n\n  /**\n   * This will be run before each test suite is started\n   *\n   * @example\n   * beforeEach(browser, done) {\n   *   done();\n   * }\n   */\n  beforeEach?(\n    browser: NightwatchAPI,\n    done: (err?: unknown) => void\n  ): void;\n\n  /**\n   * This will be run after each test suite is finished\n   *\n   * @example\n   * afterEach(browser, done) {\n   *   done();\n   * }\n   */\n  afterEach?(\n    browser: NightwatchAPI,\n    done: (err?: unknown) => void\n  ): void;\n\n  /**\n   * Called right after the command .navigateTo() is finished\n   *\n   * @example\n   * async onBrowserNavigate(browser) {\n   *   return Promise.resolve();\n   * }\n   */\n  onBrowserNavigate?(browser: NightwatchAPI): Promise<void>;\n\n  /**\n   * Called right before the command .quit() is finished\n   *\n   * @example\n   * async onBrowserQuit(browser) {\n   *   return Promise.resolve();\n   * }\n   */\n  onBrowserQuit?(browser: NightwatchAPI): Promise<void>;\n}\n"
  },
  {
    "path": "types/index.d.ts",
    "content": "// Type definitions for nightwatch 2.3\n// Project: http://nightwatchjs.org\n// Definitions by: Rahul Kavalapara <https://github.com/rkavalap>\n//                 Connor Schlesiger <https://github.com/schlesiger>\n//                 Clayton Astrom <https://github.com/ClaytonAstrom>\n//                 Lukas Beranek <https://github.com/lloiser>\n//                 Vaibhav Singh <https://github.com/vaibhavsingh97>\n//                 Andrei Rusu <https://github.com/beatfactor>\n//                 David Burns <https://github.com/AutomatedTester>\n//                 Ravi Sawlani <https://github.com/gravityvi>\n//                 Binayak Ghosh <https://github.com/swrdfish>\n//                 Harshit Agrawal <https://github.com/harshit-bs>\n//                 David Mello <https://github.com/literallyMello>\n//                 Luke Bickell <https://github.com/lukebickell>\n//                 Priyansh Garg <https://github.com/garg3133>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 4.5\n// Nightwatch Version: 3.0.0\n\nimport { Protocol } from 'devtools-protocol';\nimport {\n  By as SeleniumBy,\n  Actions,\n  Capabilities,\n  WebElement,\n  WebDriver,\n  RelativeBy,\n  locateWith as seleniumLocateWith\n} from 'selenium-webdriver';\n\nimport { Expect } from './expect';\nimport { Assert } from './assertions';\nimport { ElementFunction } from './web-element';\nimport { NightwatchGlobals } from './globals';\nimport { EnhancedPageObject } from './page-object';\nimport { NightwatchCustomCommands } from './custom-command';\nimport { NightwatchDesiredCapabilities } from './desired-capabilities';\nimport { NightwatchOptions, NightwatchTestOptions } from './nightwatch-options';\nimport { IfUnknown } from './utils';\n\nexport * from './globals';\nexport * from './expect';\nexport * from './web-element';\nexport * from './custom-assertion';\nexport * from './custom-command';\nexport * from './page-object';\nexport * from './desired-capabilities';\nexport * from './nightwatch-options';\nexport * from './assertions';\n\nexport const ELEMENT_KEY = 'element-6066-11e4-a52e-4f735466cecf';\n\nexport interface ElementResult {\n  [ELEMENT_KEY]: string;\n}\n\nexport interface JSON_WEB_OBJECT extends ElementResult {\n  getId: () => string;\n}\n\nexport type ScopedSelector = string | ElementProperties | Element | SeleniumBy | RelativeBy;\nexport type Definition = ScopedSelector | WebElement;\n\nexport type NightwatchGenericCallback<T> = (\n  this: NightwatchAPI,\n  result: NightwatchCallbackResult<T>\n) => void\n\nexport type Awaitable<T, V> = Omit<T, 'then'> & PromiseLike<V>;\n\nexport type KeysFilter<T, U> = {\n  [K in keyof T]-?: T[K] extends U ? K : never;\n}[keyof T];\n\n// tslint:disable-next-line\ntype VoidToNull<T> = T extends void ? null : T;\n\ntype ExecuteScriptFunction<ArgType extends any[], ReturnValue> = (this: { [key: string]: any }, ...args: ArgType) => ReturnValue;\n\ntype ExecuteAsyncScriptFunction<ArgType extends any[], ReturnValue> =\n  (this: { [key: string]: any }, ...args: [...innerArgs: ArgType, done: (result?: ReturnValue) => void]) => void;\n\nexport interface AppiumGeolocation {\n  latitude: number;\n  longitude: number;\n  altitude?: number;\n}\n\nexport interface NightwatchTestSuite {\n  name: string;\n  module: string;\n  group: string;\n  results: any;\n}\n\nexport interface NightwatchEnsureResult {\n  value: null;\n  returned: 1;\n}\n\nexport interface Ensure {\n  /**\n   * Ensures that the Nightwatch WebDriver client is able to switch to the designated frame.\n   */\n  ableToSwitchToFrame(\n    frame: number | WebElement | SeleniumBy\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that waits for an alert to be opened.\n   */\n  alertIsPresent(): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the given element to be disabled.\n   */\n  elementIsDisabled(\n    element: WebElement | Element | string\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the given element to be enabled.\n   */\n  elementIsEnabled(\n    element: WebElement\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the given element to be deselected.\n   */\n  elementIsNotSelected(\n    element: WebElement | Element | string\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the given element to be in the DOM, yet not displayed to the user.\n   */\n  elementIsNotVisible(\n    element: WebElement | Element | string\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the given element to be selected.\n   */\n  elementIsSelected(\n    element: WebElement | Element | string\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the given element to be displayed.\n   */\n  elementIsVisible(\n    element: WebElement | Element | string\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will loop until an element is found with the given locator.\n   */\n  elementLocated(locator: SeleniumBy): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the given element's text to contain the given substring.\n   */\n  elementTextContains(\n    element: WebElement | Element | string,\n    substr: string\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the given element's text to equal the given text.\n   */\n  elementTextIs(\n    element: WebElement | Element | string,\n    text: string\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the given element's text to match a given regular expression.\n   */\n  elementTextMatches(\n    element: WebElement | Element | string,\n    regex: RegExp\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will loop until at least one element is found with the given locator.\n   */\n  elementsLocated(\n    locator: SeleniumBy\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the given element to become stale.\n   * An element is considered stale once it is removed from the DOM, or a new page has loaded.\n   */\n  stalenessOf(\n    element: WebElement | Element | string\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the current page's title to contain the given substring.\n   */\n  titleContains(\n    substr: string\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the current page's title to match the given value.\n   */\n  titleIs(title: string): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the current page's title to match the given regular expression.\n   */\n  titleMatches(regex: RegExp): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the current page's url to contain the given substring.\n   */\n  urlContains(\n    substrUrl: string\n  ): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the current page's url to match the given value.\n   */\n  urlIs(url: string): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n\n  /**\n   * Creates a condition that will wait for the current page's url to match the given regular expression.\n   */\n  urlMatches(regex: RegExp): Awaitable<NightwatchAPI, NightwatchEnsureResult>;\n}\n\nexport interface ElementProperties {\n  /**\n   * the element selector name\n   *\n   * @example\n   * '@searchBar'\n   */\n  selector: string;\n\n  /**\n   * locator strategy can be one of\n   *  - css selector\n   *  - link text\n   *  - partial link text\n   *  - tag name\n   *  - xpath\n   *\n   * @example\n   * 'css selector'\n   */\n  locateStrategy?: LocateStrategy;\n\n  /**\n   * used to target a specific element in a query that results in multiple elements returned. Normally,\n   * only the first element is used (index = 0) but using the index property, you can specify any element within the result.\n   */\n  index?: number;\n\n  /**\n   * used to overwrite this setting when using waitForElement* commands.\n   */\n  abortOnFailure?: boolean;\n\n  /**\n   * used to overwrite the default timeout for when using waitForElement* commands or assertions.\n   */\n  timeout?: number;\n\n  /**\n   * used to overwrite the default retry interval for when using waitForElement* commands or assertions.\n   */\n  retryInterval?: number;\n\n  /**\n   * Some element commands like .click() or .getText() will throw a NoSuchElement error if the element cannot be located, causing the test to fail.\n   * If this option is set to true then this error is ignored.\n   */\n  suppressNotFoundErrors?: boolean;\n}\n\nexport interface NightwatchTypedCallbackResult<T> {\n  status: 0;\n  value: T;\n  error: Error;\n}\nexport interface NightwatchCallbackResultError {\n  status: 1; // we cannot use `number` so giving it a \"symbolic\" value allows to disjoint the union\n  value: {\n    message: string;\n    screen: string;\n    class: string;\n    stackTrace: Array<{\n      fileName: string;\n      lineNumber: number;\n      className: string;\n      methodName: string;\n    }>;\n  };\n  state: Error | string;\n}\n\nexport type NightwatchCallbackResult<T> =\n  | NightwatchTypedCallbackResult<T>\n  | NightwatchCallbackResultError;\n\nexport interface NightwatchLogEntry {\n  /**\n   * The log entry message.\n   */\n  message: string;\n\n  /**\n   * The time stamp of log entry in seconds.\n   */\n  timestamp: number;\n\n  /**\n   * The log type.\n   */\n  type: string;\n\n  /**\n   * Severity level\n   */\n  level: Level\n}\n\nexport interface Level {\n  /**\n   * the level's name.\n   */\n  name: 'ALL' | 'DEBUG' | 'FINE' | 'FINER' | 'FINEST' | 'INFO' | 'OFF' | 'SEVERE' | 'WARNING';\n\n  /**\n   * the level's numeric value.\n   */\n  value: number;\n}\n\nexport interface NightwatchKeys {\n  /** Releases all held modifier keys. */\n  NULL: string;\n  /** OS-specific keystroke sequence that performs a cancel action. */\n  CANCEL: string;\n  /** The help key. This key only appears on older Apple keyboards in place of the Insert key. */\n  HELP: string;\n  /** The backspace key. */\n  BACK_SPACE: string;\n  /** The tab key. */\n  TAB: string;\n  /** The clear key. This key only appears on full-size Apple keyboards in place of Num Lock key. */\n  CLEAR: string;\n  /** The return key. */\n  RETURN: string;\n  /** The enter (numpad) key. */\n  ENTER: string;\n  /** The shift key. */\n  SHIFT: string;\n  /** The control key. */\n  CONTROL: string;\n  /** The alt key. */\n  ALT: string;\n  /** The pause key. */\n  PAUSE: string;\n  /** The escape key. */\n  ESCAPE: string;\n\n  /** The space bar. */\n  SPACE: string;\n  /** The page up key. */\n  PAGEUP: string;\n  /** The page down key. */\n  PAGEDOWN: string;\n  /** The end key. */\n  END: string;\n  /** The home key. */\n  HOME: string;\n  /** The left arrow. */\n  ARROW_LEFT: string;\n  LEFT_ARROW: string;\n  /** The up arrow. */\n  ARROW_UP: string;\n  UP_ARROW: string;\n  /** The right arrow. */\n  ARROW_RIGHT: string;\n  RIGHT_ARROW: string;\n  /** The down arrow. */\n  ARROW_DOWN: string;\n  DOWN_ARROW: string;\n  /** The insert key. */\n  INSERT: string;\n  /** The delete key. */\n  DELETE: string;\n  /** The semicolon key. */\n  SEMICOLON: string;\n  /** The equals key. */\n  EQUALS: string;\n\n  /** The numpad zero key. */\n  NUMPAD0: string;\n  /** The numpad one key. */\n  NUMPAD1: string;\n  /** The numpad two key. */\n  NUMPAD2: string;\n  /** The numpad three key. */\n  NUMPAD3: string;\n  /** The numpad four key. */\n  NUMPAD4: string;\n  /** The numpad five key. */\n  NUMPAD5: string;\n  /** The numpad six key. */\n  NUMPAD6: string;\n  /** The numpad seven key. */\n  NUMPAD7: string;\n  /** The numpad eight key. */\n  NUMPAD8: string;\n  /** The numpad nine key. */\n  NUMPAD9: string;\n\n  /** The numpad multiply (*) key. */\n  MULTIPLY: string;\n  /** The numpad add (+) key. */\n  ADD: string;\n  /** The numpad separator (=) key. */\n  SEPARATOR: string;\n  /** The numpad subtract (-) key. */\n  SUBTRACT: string;\n  /** The numpad decimal (.) key. */\n  DECIMAL: string;\n  /** The numpad divide (/) key. */\n  DIVIDE: string;\n\n  /** The F1 key. */\n  F1: string;\n  /** The F2 key. */\n  F2: string;\n  /** The F3 key. */\n  F3: string;\n  /** The F4 key. */\n  F4: string;\n  /** The F5 key. */\n  F5: string;\n  /** The F6 key. */\n  F6: string;\n  /** The F7 key. */\n  F7: string;\n  /** The F8 key. */\n  F8: string;\n  /** The F9 key. */\n  F9: string;\n  /** The F10 key. */\n  F10: string;\n  /** The F11 key. */\n  F11: string;\n  /** The F12 key. */\n  F12: string;\n  /** The meta (Windows) key. */\n  META: string;\n  /** The command (⌘) key. */\n  COMMAND: string;\n}\n\n/**\n * Kept for backward compatibility.\n *\n * NightwatchPage provides some basic types for page objects.\n * Users can keep using these default types for page objects, but if they want\n * to be strict, they can define their own page object types by extending\n * `NightwatchCustomPageObjects` interface.\n *\n * @example\n * // using default types\n * const googlePage = browser.page.google();\n *\n * // defining types by extending NightwatchCustomPageObjects interface\n * interface GooglePage\n *   extends EnhancedPageObject<\n *     typeof googleCommands,\n *     typeof googlePage.elements\n *   > {}\n *\n * declare module 'nightwatch' {\n *   interface NightwatchCustomPageObjects {\n *     google(): GooglePage;\n *   }\n * }\n *\n * const googlePage = browser.page.google(); // type automatically inferred as GooglePage\n */\nexport type NightwatchPage = {\n  [name: string]: () => EnhancedPageObject<any, any, any>;\n} & {\n  [name: string]: NightwatchPage;\n};\n\nexport interface NamespacedApi<ReturnType = unknown> {\n  appium: AppiumCommands<ReturnType>;\n  cookies: CookiesNsCommands<ReturnType>;\n  alerts: AlertsNsCommands<ReturnType>;\n  document: DocumentNsCommands<ReturnType>;\n  logs: LogsNsCommands<ReturnType>;\n  window: WindowNsCommands<ReturnType>;\n  firefox: FirefoxNsCommands<ReturnType>;\n  chrome: ChromeNsCommands<ReturnType>;\n  network: NetworkNsCommands<ReturnType>;\n\n  assert: Assert<ReturnType>;\n  verify: Assert<ReturnType>;\n  expect: Expect;\n}\n\nexport interface NightwatchApiCommands {\n  readonly WEBDRIVER_ELEMENT_ID: string;\n  readonly browserName: string;\n  readonly platformName: string;\n  __isBrowserName(browser: string, alternateName: string): boolean;\n  __isPlatformName(platform: string): boolean;\n  isIOS(): boolean;\n  isAndroid(): boolean;\n  isMobile(): boolean;\n  isSafari(): boolean;\n  isChrome(): boolean;\n  isFirefox(): boolean;\n  isEdge(): boolean;\n  isInternetExplorer(): boolean;\n  isOpera(): boolean;\n\n  /**\n   * Whether or not Nightwatch is being used to connect to an Appium server.\n   */\n  isAppiumClient(): boolean;\n}\n\nexport interface NightwatchAPI\n  extends SharedCommands,\n  WebDriverProtocol,\n  NightwatchCustomCommands,\n  NightwatchApiCommands,\n  NamespacedApi<NightwatchAPI> {\n  baseUrl: string;\n  actions(options?: { async?: boolean; bridge?: boolean }): Actions;\n  ensure: Ensure;\n\n  page: NightwatchPage & NightwatchCustomPageObjects;\n\n  /**\n   * SessionId of the session used by the Nightwatch api.\n   */\n  sessionId: string;\n\n  /**\n   * Override the sessionId used by Nightwatch client with another session id.\n   */\n  setSessionId(sessionId: string): this;\n\n  options: NightwatchTestOptions;\n\n  Keys: NightwatchKeys;\n\n  currentTest: NightwatchTestSuite;\n\n  globals: NightwatchGlobals;\n\n  /**\n   * https://www.selenium.dev/selenium/docs/api/javascript/WebDriver.html\n   */\n  driver: WebDriver;\n\n  launchUrl: string;\n  launch_url: string;\n}\n\n// tslint:disable-next-line:no-empty-interface\nexport interface NightwatchCustomPageObjects { }\n\n/**\n * @deprecated Use `NightwatchAPI` instead.\n */\nexport interface NightwatchBrowser\n  extends NightwatchAPI,\n  NightwatchComponentTestingCommands,\n  NightwatchCustomCommands { }\n\n/**\n * @deprecated Please use the types exported by individual plugins.\n */\nexport interface NightwatchComponentTestingCommands {\n  /**\n   * @deprecated Please use the types exported by individual plugins.\n   */\n  importScript(\n    scriptPath: string,\n    options: { scriptType: string; componentType: string },\n    callback: () => void\n  ): this;\n\n  /**\n   * @deprecated Please use the types exported by individual plugins.\n   */\n  mountReactComponent(\n    componentPath: string,\n    props?: string | (() => void),\n    callback?: () => void\n  ): Element;\n\n  /**\n   * @deprecated Please use the types exported by individual plugins.\n   */\n  mountComponent(\n    componentPath: string,\n    props?: string | (() => void),\n    callback?: () => void\n  ): Element;\n\n  /**\n   * @deprecated Please use the types exported by individual plugins.\n   */\n  mountVueComponent(\n    componentPath: string,\n    options?: any,\n    callback?: () => void\n  ): Element;\n\n  /**\n   * @deprecated Please use the types exported by individual plugins.\n   */\n  launchComponentRenderer(): this;\n}\n\n// tslint:disable-next-line\nexport interface NightwatchElement extends WebElement { }\n\nexport type NightwatchTest = (browser?: NightwatchBrowser) => void;\n\nexport interface NightwatchTestFunctions {\n  before?: NightwatchTestHook;\n  after?: NightwatchTestHook;\n  beforeEach?: NightwatchTestHook;\n  afterEach?: NightwatchTestHook;\n\n  '@tags'?: string | string[];\n  '@disabled'?: boolean;\n\n  [key: string]: any;\n}\n\nexport type NightwatchTestHook = (\n  browser: NightwatchBrowser,\n  done: (err?: unknown) => void\n) => void;\n\nexport class Element {\n  name: string | undefined;\n  locateStrategy: LocateStrategy;\n  index: number;\n  selector: string | undefined; // and probably `RelativeBy`.\n  pseudoSelector: string | null;\n\n  resolvedElement: string | null;\n  parent: any;\n  usingRecursion: boolean;\n\n  webElement?: WebElement;\n  webElementId?: string;\n\n  abortOnFailure?: boolean;\n  suppressNotFoundErrors?: boolean;\n  retryInterval?: number;\n  message?: string;\n  timeout?: number;\n}\n\ntype ElementGlobalDefinition = string | SeleniumBy | RelativeBy | { selector: string; locateStrategy?: string } | { using: string, value: string };\n\nexport interface ElementGlobal extends Element {\n  /**\n   * Get the server-assigned opaque ID assigned to this element.\n   */\n  getId(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void\n  ): Awaitable<NightwatchAPI, string>;\n\n  /**\n   * Locates the descendants of this element that match the given search criteria, and returns the first one.\n   *\n   * If no `selector` is passed, returns the [WebElement](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html)\n   * instance for this element.\n   */\n  findElement(): Awaitable<NightwatchAPI, WebElement>;\n  findElement(\n    selector: ElementGlobalDefinition,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<WebElement>) => void\n  ): Awaitable<NightwatchAPI, WebElement>;\n\n  /**\n   * Locates and wraps the first element, that match the given search criteria in the descendants of this element, in global element() api object.\n   *\n   * If no `selector` is passed, returns the [WebElement](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html)\n   * instance for this element.\n   */\n  find(): Awaitable<NightwatchAPI, WebElement>;\n  find(\n    selector: ElementGlobalDefinition,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<ElementGlobal | null>) => void\n  ): Awaitable<NightwatchAPI, ElementGlobal | null>;\n\n  get: ElementGlobal['find'];\n  element: ElementGlobal['find'];\n\n  /**\n   * Locates all of the descendants of this element that match the given search criteria.\n   */\n  findElements(\n    selector: ElementGlobalDefinition,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<WebElement[]>) => void\n  ): Awaitable<NightwatchAPI, WebElement[]>;\n\n  findAll(\n    selector: ElementGlobalDefinition,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<ElementGlobal[]>) => void\n  ): Awaitable<NightwatchAPI, ElementGlobal[]>;\n\n  /**\n   * Clear the `value` of this element. This command has no effect if the underlying DOM element\n   * is neither a text INPUT element nor a TEXTAREA element.\n   *\n   * @see https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#clear\n   */\n  clear(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void\n  ): Awaitable<NightwatchAPI, null>;\n\n  /**\n   * Clicks on this element.\n   *\n   * @see https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#click\n   */\n  click(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void\n  ): Awaitable<NightwatchAPI, null>;\n\n  /**\n   * Get the computed WAI-ARIA label of element.\n   */\n  getAccessibleName(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void\n  ): Awaitable<NightwatchAPI, string>;\n  /**\n   * Get the computed WAI-ARIA label of element.\n   */\n  accessibleName: ElementGlobal['getAccessibleName'];\n\n  /**\n   * Get the computed WAI-ARIA role of element.\n   */\n  getAriaRole(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void\n  ): Awaitable<NightwatchAPI, string>;\n  /**\n   * Get the computed WAI-ARIA role of element.\n   */\n  ariaRole: ElementGlobal['getAriaRole'];\n\n  /**\n   * Retrieves the current value of the given attribute of this element.\n   *\n   * @see https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#getAttribute\n   */\n  getAttribute(\n    attributeName: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string | null>) => void\n  ): Awaitable<NightwatchAPI, string | null>;\n  /**\n   * Retrieves the current value of the given attribute of this element.\n   *\n   * @see https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#getAttribute\n   */\n  attr: ElementGlobal['getAttribute'];\n  /**\n   * Retrieves the current value of the given attribute of this element.\n   *\n   * @see https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#getAttribute\n   */\n  attribute: ElementGlobal['getAttribute'];\n\n  /**\n   * Retrieves the value of a computed style property for this instance.\n   *\n   * @see https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#getCssValue\n   */\n  getCssValue(\n    cssStyleProperty: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void\n  ): Awaitable<NightwatchAPI, string>;\n  /**\n   * Retrieves the value of a computed style property for this instance.\n   *\n   * @see https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#getCssValue\n   */\n  css: ElementGlobal['getCssValue'];\n\n  /**\n   * Retrieves the value of the given property of this element.\n   */\n  getProperty(\n    propertyName: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string | null>) => void\n  ): Awaitable<NightwatchAPI, string | null>;\n  /**\n   * Retrieves the value of the given property of this element.\n   */\n  property: ElementGlobal['getProperty'];\n  /**\n   * Retrieves the value of the given property of this element.\n   */\n  prop: ElementGlobal['getProperty'];\n\n  /**\n   * Returns an object describing an element's location, in pixels relative to the document element, and the element's size in pixels.\n   */\n  getRect(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<NightwatchSizeAndPosition>) => void\n  ): Awaitable<NightwatchAPI, NightwatchSizeAndPosition>;\n  /**\n   * Returns an object describing an element's location, in pixels relative to the document element, and the element's size in pixels.\n   */\n  rect: ElementGlobal['getRect'];\n\n  /**\n   * Retrieves the element's tag name.\n   */\n  getTagName(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void\n  ): Awaitable<NightwatchAPI, string>;\n  /**\n   * Retrieves the element's tag name.\n   */\n  tagName: ElementGlobal['getTagName'];\n\n  /**\n   * Get the visible (i.e. not hidden by CSS) innerText of this element, including sub-elements, without any leading or trailing whitespace.\n   */\n  getText(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void\n  ): Awaitable<NightwatchAPI, string>;\n  /**\n   * Get the visible (i.e. not hidden by CSS) innerText of this element, including sub-elements, without any leading or trailing whitespace.\n   */\n  text: ElementGlobal['getText'];\n\n  /**\n   * Types a key sequence on the DOM element represented by this instance.\n   *\n   * @example\n   * element(<selector>).sendKeys(1, 'something', browser.Keys.SPACE, Promise.resolve(2));\n   *\n   * @see https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#sendKeys\n   */\n  sendKeys(\n    ...args: Array<string | number | PromiseLike<string> | PromiseLike<number>>\n  ): Awaitable<NightwatchAPI, null>;\n\n  /**\n   * Submits the form containing this element (or this element if it is itself a FORM element).\n   * This command is a no-op if the element is not contained in a form.\n   *\n   * @see https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html#submit\n   */\n  submit(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void\n  ): Awaitable<NightwatchAPI, null>;\n\n  /**\n   * Take a screenshot of the visible region encompassed by this element's bounding rectangle.\n   */\n  takeScreenshot(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void\n  ): Awaitable<NightwatchAPI, string>;\n  /**\n   * Take a screenshot of the visible region encompassed by this element's bounding rectangle.\n   */\n  screenshot: ElementGlobal['takeScreenshot'];\n\n  /**\n   * Test whether this element is currently displayed.\n   */\n  isDisplayed(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<boolean>) => void\n  ): Awaitable<NightwatchAPI, boolean>;\n\n  /**\n   * Tests whether this element is enabled, as dictated by the `disabled` attribute.\n   */\n  isEnabled(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<boolean>) => void\n  ): Awaitable<NightwatchAPI, boolean>;\n\n  /**\n   * Tests whether this element is selected.\n   */\n  isSelected(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<boolean>) => void\n  ): Awaitable<NightwatchAPI, boolean>;\n\n  /**\n   * Get the [WebElement](https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html) instance for this element.\n   */\n  getWebElement(): Awaitable<NightwatchAPI, WebElement>;\n\n  isComponent?: boolean;\n}\n\nexport function globalElement(\n  locator: Definition,\n  options?: {\n    isComponent?: boolean;\n    type: string;\n  }\n): ElementGlobal;\n\nexport type NightwatchTests = NightwatchTestFunctions;\n\nexport class DescribeInstance {\n  '[instance]': any;\n  '[attributes]': {};\n  '[client]': NightwatchClient;\n\n  /**\n   * Title of the describe suite.\n   */\n  get name(): string;\n\n  /**\n   * Get or set tags for the test suite.\n   *\n   * @see https://nightwatchjs.org/guide/running-tests/filtering-by-test-tags.html\n   */\n  get tags(): string | string[];\n  set tags(value: string | string[]);\n\n  /**\n   * Enable if the current test is a unit/integration test\n   * (no webdriver session is required).\n   */\n  get unitTest(): boolean;\n  set unitTest(value: boolean);\n\n  /**\n   * Set to false if you'd like the browser window to be kept open\n   * in case of a failure or error (useful for debugging).\n   */\n  get endSessionOnFail(): boolean;\n  set endSessionOnFail(value: boolean);\n\n  /**\n   * Set to false if you'd like the rest of the test cases/test steps\n   * to be executed in the event of an assertion failure/error.\n   */\n  get skipTestcasesOnFail(): boolean;\n  set skipTestcasesOnFail(value: boolean);\n\n  /**\n   * Set to true if you'd like this test suite to be skipped by the\n   * test runner.\n   */\n  get disabled(): boolean;\n  set disabled(value: boolean);\n\n  /**\n   * Get or set testsuite specific capabilities.\n   */\n  get desiredCapabilities(): NightwatchDesiredCapabilities;\n  set desiredCapabilities(value: NightwatchDesiredCapabilities);\n\n  /**\n   * Get available page objects.\n   */\n  get page(): NightwatchAPI['page'];\n\n  /**\n   * Get all current globals.\n   */\n  get globals(): NightwatchGlobals;\n\n  /**\n   * Get all current settings.\n   */\n  get settings(): NightwatchOptions;\n\n  /**\n   * Get all current cli arguments.\n   */\n  get argv(): { [key: string]: any };\n\n  /**\n   * Get all current mocha options.\n   */\n  get mochaOptions(): { [key: string]: any } | undefined;\n\n  /**\n   * Control the unit test timeout.\n   *\n   * Control the assertion and element commands timeout until when\n   * an element should be located or assertion passed.\n   *\n   * @param value Timeout in `ms`\n   */\n  timeout(value: number): void;\n\n  /**\n   * Get the assertion and element commands timeout until when\n   * an element would be located or assertion passed.\n   *\n   * @returns Timeout in `ms`\n   */\n  waitForTimeout(): number;\n\n  /**\n   * Control the assertion and element commands timeout until when\n   * an element should be located or assertion passed.\n   *\n   * @param value Timeout in `ms`\n   */\n  waitForTimeout(value: number): void;\n\n  /**\n   * Get the polling interval between re-tries for assertions\n   * or element commands.\n   *\n   * @returns Time interval in `ms`\n   */\n  waitForRetryInterval(): number;\n\n  /**\n   * Control the polling interval between re-tries for assertions\n   * or element commands.\n   *\n   * @param value Time interval in `ms`\n   */\n  waitForRetryInterval(value: number): void;\n\n  /**\n   * Control the polling interval between re-tries for assertions\n   * or element commands.\n   *\n   * @param value Time interval in `ms`\n   */\n  retryInterval(value: number): void;\n\n  /**\n   * How many time to retry a failed testcase inside this test suite\n   */\n  retries(n: number): void;\n\n  /**\n   * How many times to retry the current test suite in case of an\n   * assertion failure or error\n   */\n  suiteRetries(n: number): void;\n}\n\nexport type ExtendDescribeThis<T> = DescribeInstance & {\n  [P in keyof T]?: T[P];\n};\n\ninterface SuiteFunction {\n  (title: string, fn?: (this: DescribeInstance) => void): this;\n  only: ExclusiveSuiteFunction;\n  skip: PendingSuiteFunction;\n}\n\ninterface ExclusiveSuiteFunction {\n  (title: string, fn?: (this: DescribeInstance) => void): this;\n}\n\ninterface PendingSuiteFunction {\n  (title: string, fn?: (this: DescribeInstance) => void): this | void;\n}\n\ninterface ExclusiveTestFunction {\n  (fn: NormalFunc | AsyncFunc): this;\n  (title: string, fn: NormalFunc | AsyncFunc): this;\n}\n\ninterface PendingTestFunction {\n  (fn: NormalFunc | AsyncFunc): this;\n  (title: string, fn: NormalFunc | AsyncFunc): this;\n}\n\ntype NormalFunc = (this: DescribeInstance, browser: NightwatchBrowser) => void;\ntype AsyncFunc = (\n  this: DescribeInstance,\n  browser: NightwatchBrowser\n) => PromiseLike<any>;\ninterface TestFunction {\n  (fn: NormalFunc | AsyncFunc): this;\n  (title: string, fn: NormalFunc | AsyncFunc): this;\n  only: ExclusiveTestFunction;\n  skip: PendingTestFunction;\n  retries(n: number): void;\n}\n\ntype NightwatchBddTestHookCallback = (\n  this: DescribeInstance,\n  browser: NightwatchBrowser,\n  done: (err?: any) => void\n) => void;\n\ntype NightwatchBddTestHook = (callback: NightwatchBddTestHookCallback) => void;\n\ndeclare global {\n  const describe: SuiteFunction;\n  const xdescribe: PendingSuiteFunction;\n  const context: SuiteFunction;\n  const xcontext: PendingSuiteFunction;\n  const test: TestFunction;\n  const it: TestFunction;\n  const xit: PendingTestFunction;\n  const specify: TestFunction;\n  const xspecify: PendingTestFunction;\n  const before: NightwatchBddTestHook;\n  const after: NightwatchBddTestHook;\n  const beforeEach: NightwatchBddTestHook;\n  const afterEach: NightwatchBddTestHook;\n}\n\nexport interface NightwatchClient extends NightwatchClientObject {\n  argv: { [key: string]: any };\n  client: NightwatchClientObject;\n  configLocateStrategy: \"css selector\" | \"xpath\";\n  // TODO: Add missing properties, like:\n  // elementLocator\n  // httpOpts\n  // initialCapabilities\n  // queue\n  // reporter\n  unitTestingMode: boolean;\n  usingCucumber: boolean;\n}\n\nexport interface NightwatchClientObject {\n  api: NightwatchAPI;\n  options: NightwatchOptions;\n  settings: NightwatchOptions;\n  locateStrategy: LocateStrategy;\n  // TODO: Add missing properties, like:\n  // reporter: reporter\n  // elementLocator\n  sessionId: string | null;\n}\n\nexport interface HttpRequestOptions {\n  /**\n   * The pathname of the endpoint to call. Ex: `'/session/:sessionId/url'`.\n   *\n   * Alternatively, url property could be provided with the full URL.\n   */\n  path?: string;\n  data?: unknown;\n\n  /**\n   * For custom-commands, set to `this.api.sessionId`.\n   */\n  sessionId: string;\n\n  method: 'POST' | 'GET' | 'DELETE' | 'PUT';\n  use_ssl?: boolean;\n  host?: string;\n  port?: number;\n\n  /**\n   * The full URL to call. Ex: `http://localhost:4444/session/:sessionId/url`.\n   */\n  url?: string;\n\n  auth?: {\n    user: string;\n    pass: string;\n  }\n}\n\nexport interface CommandInstance {\n  get api(): NightwatchAPI;\n  get client(): NightwatchClient;\n  get commandArgs(): unknown[];\n  get commandFileName(): string;\n  get driver(): WebDriver;\n  get isES6AsyncCommand(): boolean;\n  get reuseBrowser(): boolean;\n\n  /**\n   * Direct access to methods present in the `lib/transport/selenium-webdriver/method-mappings.js` file\n   * of Nightwatch code.\n   *\n   * TODO: complete the type definition.\n   *\n   * For now, you would need to create custom interface to use this property, like below:\n   * ```ts\n   * interface TransportActions {\n   *   getCurrentUrl(): Promise<NightwatchCallbackResult<string>>;\n   * }\n   * ```\n   * then use it inside your custom command like:\n   * ```ts\n   * const currentUrl = await (this.transportActions as TransportActions).getCurrentUrl();\n   * ```\n   */\n  get transportActions(): unknown;\n\n  /**\n   * Directly call the HTTP endpoints of the Selenium/WebDriver server.\n   *\n   * This is useful when you need to call a command that is not directly supported by Nightwatch API.\n   *\n   * @see https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html#postdoc-directly-calling-seleniumwebdriver-endpoints\n   */\n  httpRequest(options: HttpRequestOptions): Promise<unknown>;\n\n  toString(): string;\n  complete(...args: unknown[]): void;\n}\n\nexport interface CreateClientParams {\n  browserName?: string | null;\n  headless?: boolean;\n  silent?: boolean;\n  output?: boolean;\n  useAsync?: boolean;\n  env?: string | null;\n  timeout?: number | null;\n  parallel?: boolean;\n  reporter?: any;\n  globals?: Partial<NightwatchGlobals>;\n  devtools?: boolean;\n  debug?: boolean;\n  enable_global_apis?: boolean;\n  config?: string;\n  test_settings?: Partial<NightwatchOptions>;\n}\n\nexport interface Nightwatch {\n  /**\n   * Internal method in Nightwatch.\n   */\n  cli(callback: () => void): void;\n\n  /**\n   * Internal method in Nightwatch.\n   */\n  client(settings: NightwatchOptions, reporter?: any, argv?: {}, skipInt?: boolean): this;\n\n  /**\n   * Internal method in Nightwatch.\n   */\n  CliRunner(argv?: {}): this; // TODO: return type is `CliRunner` instance.\n\n  /**\n   * Internal method in Nightwatch.\n   */\n  initClient(opts?: {}): this;\n\n  /**\n   * Internal method in Nightwatch.\n   *\n   * @deprecated\n   */\n  runner(argv?: {}, done?: () => void, settings?: {}): Promise<void>;\n\n  /**\n   * Internal method in Nightwatch.\n   */\n  runTests(testSource: string | string[], settings?: any, ...args: any[]): Promise<void>;\n\n  /**\n   * Creates a new Nightwatch client that can be used to create WebDriver sessions.\n   *\n   * @example\n   * const Nightwatch = require('nightwatch');\n   *\n   * const client = Nightwatch.createClient({\n   *   headless: true,\n   *   output: true,\n   *   silent: true, // set to false to enable verbose logging\n   *   browserName: 'firefox', // can be either: firefox, chrome, safari, or edge\n   *\n   *   // set the global timeout to be used with waitFor commands and when retrying assertions/expects\n   *   timeout: 10000,\n   *\n   *   // set the current test environment from the nightwatch config\n   *   env: null,\n   *\n   *   // any additional capabilities needed\n   *   desiredCapabilities: {\n   *\n   *   },\n   *\n   *   // can define/overwrite test globals here;\n   *   // when using a third-party test runner only the global hooks onBrowserNavigate/onBrowserQuit are supported\n   *   globals: {},\n   *\n   *   // when the test runner used supports running tests in parallel;\n   *   // set to true if you need the webdriver port to be randomly generated\n   *   parallel: false,\n   *\n   *   // All other Nightwatch config settings can be overwritten here, such as:\n   *   disable_colors: false\n   * });\n   *\n   * @see https://nightwatchjs.org/api/programmatic/#programmatic-api\n   */\n  createClient({\n    headless,\n    silent,\n    output,\n    useAsync,\n    env,\n    timeout,\n    parallel,\n    reporter,\n    browserName,\n    globals,\n    devtools,\n    debug,\n    enable_global_apis,\n    config,\n    test_settings\n  }?: CreateClientParams): NightwatchProgrammaticAPIClient;\n\n  // TODO: add the following missing properties\n  // Logger\n  // element (only available after createClient is called)\n\n  // Not adding named-exports (Namespaced API) here because those\n  // would go away from Nightwatch interface after migrating to TypeScript,\n  // because then named-exports will be exported directly instead\n  // of first adding them to Nightwatch (default export).\n  browser: NightwatchAPI;\n  app: NightwatchAPI;\n  by: typeof SeleniumBy;\n  Capabilities: typeof Capabilities;\n  Key: NightwatchKeys;\n}\n\nexport interface NightwatchProgrammaticAPIClient {\n  /**\n   * Create a new browser session.\n   *\n   * Returns [NightwatchAPI](https://nightwatchjs.org/api/) object.\n   *\n   * @example\n   * const browser = await client.launchBrowser();\n   */\n  launchBrowser(): Promise<NightwatchAPI>;\n\n  /**\n   * Update the initially specified capabilities.\n   *\n   * @example\n   * client.updateCapabilities({\n   *   testCapability: 'one, two, three'\n   * });\n   */\n  updateCapabilities(value: {} | (() => {})): void;\n\n  nightwatch_client: NightwatchClient;\n  settings: NightwatchOptions;\n  // TODO: 'transport' property missing\n}\n\nexport type LocateStrategy =\n  | 'class name'\n  | 'css selector'\n  | 'id'\n  | 'name'\n  | 'link text'\n  | 'partial link text'\n  | 'tag name'\n  | 'xpath'\n  // Appium-specific strategies\n  | 'accessibility id'\n  | '-android uiautomator'\n  | '-ios predicate string'\n  | '-ios class chain';\n\nexport type NightwatchLogTypes =\n  | 'client'\n  | 'driver'\n  | 'browser'\n  | 'server'\n  | 'performance';\n\nexport interface SharedCommands extends ClientCommands, ElementCommands { }\n\nexport interface WindowPosition {\n  x: number;\n  y: number;\n}\n\n// tslint:disable-next-line\nexport interface NightwatchPosition extends WindowPosition { }\n\nexport interface WindowSize {\n  height: number;\n  width: number;\n}\n\n// tslint:disable-next-line\nexport interface NightwatchSize extends WindowSize { }\n\nexport type WindowSizeAndPosition = WindowPosition & WindowSize;\n\nexport type NightwatchSizeAndPosition = WindowSizeAndPosition;\n\nexport type WindowType = 'tab' | 'window';\n\nexport interface ChromiumClientCommands {\n  /**\n   * Mock the geolocation of the browser.\n   *\n   * Call without any arguments to reset the geolocation.\n   *\n   * @example\n   *  describe('mock geolocation', function() {\n   *    it('sets the geolocation to Tokyo, Japan and then resets it', () => {\n   *      browser\n   *        .setGeolocation({\n   *          latitude: 35.689487,\n   *          longitude: 139.691706,\n   *          accuracy: 100\n   *        })  // sets the geolocation to Tokyo, Japan\n   *        .navigateTo('https://www.gps-coordinates.net/my-location')\n   *        .pause(3000)\n   *        .setGeolocation()  // resets the geolocation\n   *        .navigateTo('https://www.gps-coordinates.net/my-location')\n   *        .pause(3000);\n   *    });\n   *  });\n   *\n   * @see https://nightwatchjs.org/guide/network-requests/mock-geolocation.html\n   */\n  setGeolocation(\n    coordinates?: { latitude: number; longitude: number; accuracy?: number },\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Override device mode/dimensions.\n   *\n   * @example\n   *  describe('modify device dimensions', function() {\n   *    it('modifies the device dimensions and then resets it', function() {\n   *      browser\n   *        .setDeviceDimensions({\n   *          width: 400,\n   *          height: 600,\n   *          deviceScaleFactor: 50,\n   *          mobile: true\n   *        })\n   *        .navigateTo('https://www.google.com')\n   *        .pause(1000)\n   *        .setDeviceDimensions()  // resets the device dimensions\n   *        .navigateTo('https://www.google.com')\n   *        .pause(1000);\n   *    });\n   *  });\n   *\n   * @see https://nightwatchjs.org/guide/mobile-web-testing/override-device-dimensions.html\n   */\n  setDeviceDimensions(\n    metrics?: {\n      width?: number;\n      height?: number;\n      deviceScaleFactor?: number;\n      mobile?: boolean;\n    },\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Get the performance metrics from the browser. Metrics collection\n   * only begin after `enablePerformanceMetrics()` command is called.\n   *\n   * @returns A promise that contains metrics collected between the\n   * last call to `enablePerformanceMetrics()` command and this command.\n   *\n   * @example\n   *  describe('collect performance metrics', function() {\n   *    it('enables the metrics collection, does some stuff and collects the metrics', function() {\n   *      browser\n   *        .enablePerformanceMetrics()\n   *        .navigateTo('https://www.google.com')\n   *        .getPerformanceMetrics((result) => {\n   *          if (result.status === 0) {\n   *            const metrics = result.value;\n   *            console.log(metrics);\n   *          }\n   *        });\n   *    });\n   *  });\n   *\n   * @see https://web.dev/metrics/\n   * @see https://pptr.dev/api/puppeteer.page.metrics/\n   */\n  getPerformanceMetrics(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<{ [metricName: string]: number }>\n    ) => void\n  ): Awaitable<this, { [metricName: string]: number }>;\n\n  /**\n   * Enable/disable the collection of performance metrics in the browser. Metrics\n   * collection only begin after this command is called.\n   *\n   * @example\n   *  describe('collect performance metrics', function() {\n   *    it('enables the metrics collection, does some stuff and collects the metrics', function() {\n   *      browser\n   *        .enablePerformanceMetrics()\n   *        .navigateTo('https://www.google.com')\n   *        .getPerformanceMetrics((result) => {\n   *          if (result.status === 0) {\n   *            const metrics = result.value;\n   *            console.log(metrics);\n   *          }\n   *        });\n   *    });\n   *  });\n   *\n   * @see https://web.dev/metrics/\n   * @see https://pptr.dev/api/puppeteer.page.metrics/\n   */\n  enablePerformanceMetrics(\n    enable?: boolean,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Take heap snapshot and save it as a `.heapsnapshot` file.\n   * The saved snapshot file can then be loaded into Chrome\n   * DevTools' Memory tab for inspection.\n   *\n   * The contents of the heap snapshot are also available in the `value`\n   * property of the `result` argument passed to the callback, in\n   * string-serialized JSON format.\n   *\n   * @returns A promise that contains heap snapshot in string-serialized\n   * JSON format.\n   *\n   * @example\n   *  describe('take heap snapshot', function() {\n   *    it('takes heap snapshot and saves it as snap.heapsnapshot file', function() {\n   *      browser\n   *        .navigateTo('https://www.google.com')\n   *        .takeHeapSnapshot('./snap.heapsnapshot');\n   *    });\n   *  });\n   *\n   * @see https://nightwatchjs.org/guide/running-tests/take-heap-snapshot.html\n   */\n  takeHeapSnapshot(\n    heapSnapshotLocation?: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Automate the input of basic auth credentials whenever they arise.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser\n   *      .registerBasicAuth('test-username', 'test-password')\n   *      .navigateTo('http://browserspy.dk/password-ok.php');\n   *  };\n   *\n   * @see https://nightwatchjs.org/api/registerBasicAuth.html#apimethod-container\n   */\n  registerBasicAuth(\n    username: string,\n    password: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  captureNetworkRequests: NetworkNsCommands<this>['captureRequests'];\n\n  mockNetworkResponse: NetworkNsCommands<this>['mockResponse'];\n\n  setNetworkConditions: NetworkNsCommands<this>['setConditions'];\n\n  captureBrowserConsoleLogs: LogsNsCommands<this>['captureBrowserConsoleLogs'];\n\n  captureBrowserExceptions: LogsNsCommands<this>['captureBrowserExceptions'];\n}\n\nexport interface SharedClientCommands {\n  /**\n   * Delete the cookie with the given name. This command is a no-op if there is no such cookie visible to the current page.\n   *\n   * @example\n   * this.demoTest = function() {\n   *   browser.deleteCookie(\"test_cookie\", function() {\n   *     // do something more in here\n   *   });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/deleteCookie.html\n   *\n   * @deprecated In favour of `.cookies.delete()`.\n   */\n  deleteCookie(\n    cookieName: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Delete all cookies visible to the current page.\n   *\n   * @example\n   * this.demoTest = function() {\n   *   browser.deleteCookies(function() {\n   *     // do something more in here\n   *   });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/deleteCookies.html\n   *\n   * @deprecated In favour of `.cookies.deleteAll()`.\n   */\n  deleteCookies(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Ends the session. Uses session protocol command.\n   *\n   * @example\n   * this.demoTest = function () {\n   *   browser.end();\n   * };\n   *\n   * @see https://nightwatchjs.org/api/end.html\n   */\n  end(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Retrieve a single cookie visible to the current page. The cookie is returned as a cookie JSON object,\n   * as defined [here](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object).\n   *\n   * Uses `cookie` protocol command.\n   *\n   * @example\n   * this.demoTest = function() {\n   *   browser.getCookie(name, function callback(result) {\n   *     this.assert.equal(result.value, '123456');\n   *     this.assert.equals(result.name, 'test_cookie');\n   *   });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getCookie.html\n   *\n   * @deprecated In favour of `.cookies.get()`.\n   */\n  getCookie(\n    name: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<Cookie>\n    ) => void\n  ): Awaitable<this, Cookie>;\n\n  /**\n   * Retrieve all cookies visible to the current page. The cookies are returned as an array of cookie JSON object,\n   * as defined [here](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object).\n   *\n   * Uses `cookie` protocol command.\n   *\n   * @example\n   * this.demoTest = function() {\n   *   browser.getCookies(function callback(result) {\n   *     this.assert.equal(result.value.length, 1);\n   *     this.assert.equals(result.value[0].name, 'test_cookie');\n   *   });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getCookies.html\n   *\n   * @deprecated In favour of `.cookies.getAll()`.\n   */\n  getCookies(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<Cookie[]>\n    ) => void\n  ): Awaitable<this, Cookie[]>;\n\n  /**\n   * Gets a log from Selenium.\n   *\n   * @example\n   * this.demoTest = function() {\n   *   this.getLog('browser', function(logEntriesArray) {\n   *     console.log('Log length: ' + logEntriesArray.length);\n   *     logEntriesArray.forEach(function(log) {\n   *        console.log('[' + log.level + '] ' + log.timestamp + ' : ' + log.message);\n   *      });\n   *   });\n   * };\n   *\n   * @see https://nightwatchjs.org/api/getLog.html\n   */\n  getLog(\n    typestring: string,\n    callback?: (this: NightwatchAPI, log: NightwatchLogEntry[]) => void\n  ): Awaitable<this, NightwatchLogEntry[]>;\n\n  /**\n   * Gets the available log types. More info about log types in WebDriver can be found here: https://github.com/SeleniumHQ/selenium/wiki/Logging\n   *\n   * @example\n   * this.demoTest = function() {\n   *   this.getLogTypes(function(typesArray) {\n   *     console.log(typesArray);\n   *   });\n   * };\n   *\n   * @see https://nightwatchjs.org/api/getLogTypes.html\n   */\n  getLogTypes(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchLogTypes[]\n    ) => void\n  ): Awaitable<\n    this,\n    NightwatchLogTypes[]\n  >;\n\n  /**\n   * Returns the title of the current page. Uses title protocol command.\n   *\n   * @example\n   *  this.demoTest = function () {\n   *    browser.getTitle(function(title) {\n   *      this.assert.equal(typeof title, 'string');\n   *      this.assert.equal(title, 'Nightwatch.js');\n   *    });\n   *  };\n   *\n   * @see https://nightwatchjs.org/api/getTitle.html\n   */\n  getTitle(\n    callback?: (this: NightwatchAPI, result: string) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * This command is an alias to url and also a convenience method when called without any arguments in the sense\n   * that it performs a call to .url() with passing the value of `launch_url` field from the settings file.\n   * Uses `url` protocol command.\n   *\n   * @example\n   * this.demoTest = function () {\n   *   browser.init();\n   * };\n   *\n   * @see https://nightwatchjs.org/api/init.html\n   */\n  init(\n    url?: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Utility command to load an external script into the page specified by url.\n   *\n   * @example\n   * this.demoTest = function() {\n   *   this.injectScript(\"{script-url}\", function() {\n   *     // we're all done here.\n   *   });\n   * };\n   *\n   * @see https://nightwatchjs.org/api/injectScript.html\n   *\n   * @deprecated In favour of `.document.injectScript()`.\n   */\n  injectScript(\n    scriptUrl: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<WebElement>\n    ) => void,\n  ): Awaitable<this, WebElement>;\n  injectScript(\n    scriptUrl: string,\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<WebElement>\n    ) => void,\n  ): Awaitable<this, WebElement>;\n\n  /**\n   * Utility command to test if the log type is available.\n   *\n   * @example\n   * this.demoTest = function() {\n   *   browser.isLogAvailable('browser', function(isAvailable) {\n   *     // do something more in here\n   *   });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/isLogAvailable.html\n   */\n  isLogAvailable(\n    typeString: string,\n    callback?: (this: NightwatchAPI, result: boolean) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   * Maximizes the current window.\n   *\n   * @example\n   *  this.demoTest = function () {\n   *    browser.maximizeWindow();\n   *  };\n   *\n   * @see https://nightwatchjs.org/api/maximizeWindow.html\n   *\n   * @deprecated In favour of `.window.maximize()`.\n   */\n  maximizeWindow(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Suspends the test for the given time in milliseconds. If the milliseconds argument is missing it will suspend the test indefinitely\n   *\n   * @example\n   * this.demoTest = function () {\n   *   browser.pause(1000);\n   *   // or suspend indefinitely\n   *   browser.pause();\n   * };\n   *\n   * @see https://nightwatchjs.org/api/pause.html\n   */\n  pause(\n    ms?: number,\n    callback?: (this: NightwatchAPI) => void\n  ): Awaitable<this, undefined>;\n\n  /**\n   * This command halts the test execution and provides users with a REPL interface where they can type\n   * any of the available Nightwatch commands and the command will be executed in the running browser\n   * in real-time.\n   *\n   * This can be used to debug why a certain command in not working as expected, find the correct\n   * locators for your assertions or just play around with the available Nightwatch commands.\n   *\n   * You can also expose local variables and helper functions from your test to the REPL by passing\n   * them via the `context` option; they will then be available in the debug prompt alongside\n   * the `browser` object.\n   * \n   * @example\n   * // async function is required while using the debug\n   * // command to get the correct result as output.\n   * it('demos debug command', async function (browser) {\n   *   const someLocalVariable = 'something random';\n   *   function someLocalFunction() {\n   *     return 'local function result';\n   *   }\n   *\n   *   // with default options\n   *   browser.debug();\n   *\n   *   // with no auto-complete\n   *   browser.debug({preview: false});\n   *\n   *   // with a timeout of 6000 ms (time for which the interface\n   *   // would wait for a result).\n   *   browser.debug({timeout: 6000});\n   *\n   *   // expose local variables/functions to the debug REPL\n   *   browser.debug({\n   *     // both values below will be directly available in the debug REPL\n   *     context: {someLocalVariable, someLocalFunction}\n   *   });\n   * });\n   *\n   * @see https://nightwatchjs.org/api/debug.html\n   */\n  debug(\n    config?: { useGlobal?: boolean; preview?: boolean; timeout?: number; context?: Record<string, any> },\n    callback?: (this: NightwatchAPI) => void\n  ): Awaitable<this, undefined>;\n\n  /**\n   * A simple perform command which allows access to the Nightwatch API in a callback. Can be useful if you want to read variables set by other commands.\n   *\n   * The callback signature can have up to two parameters.\n   *  - no parameters: callback runs and perform completes immediately at the end of the execution of the callback.\n   *  - one parameter: allows for asynchronous execution within the callback providing a done callback function for completion as the first argument.\n   *  - two parameters: allows for asynchronous execution with the Nightwatch `api` object passed in as the first argument, followed by the done callback.\n   *\n   * @example\n   * describe('perform example', function() {\n   *   var elementValue;\n   *\n   *   it('basic perform', function(browser) {\n   *     browser\n   *       .getValue('.some-element', function(result) {\n   *         elementValue = result.value;\n   *       })\n   *       // other stuff going on ...\n   *\n   *       // self-completing callback\n   *       .perform(function() {\n   *         console.log('elementValue', elementValue);\n   *         // without any defined parameters, perform\n   *         // completes immediately (synchronously)\n   *       })\n   *\n   *       // returning a Promise\n   *       .perform(async function() {\n   *         // `this` can be used to directly access Nightwatch API\n   *         const sessionId = await this.sessionId;\n   *         console.log('session id', sessionId);\n   *       })\n   *\n   *       // DEPRECATED: asynchronous completion using done\n   *       .perform(function(done: (result: string) => void) {\n   *         // potentially some async stuff going on\n   *         // `this` can be used to directly access Nightwatch API\n   *         this.getTitle((result) => {\n   *           // when finished, call the done callback\n   *           done(result.value);\n   *         });\n   *       })\n   *\n   *       // DEPRECATED: asynchronous completion including api (client)\n   *       .perform(function(client: NightwatchAPI, done: () => void) {\n   *         this.navigateTo('https://google.com/', () => {\n   *           done();\n   *         });\n   *       });\n   *   });\n   *\n   *   it('perform with async', function(browser) {\n   *     const result = await browser.perform(async function() {\n   *       // `this` can be used to directly access Nightwatch API\n   *       const pageTitle = await this.getTitle();\n   *\n   *       return 100;\n   *     });\n   *     console.log('result:', result); // 100\n   *   })\n   * };\n   */\n  perform<ReturnValue>(\n    callback: (this: NightwatchAPI) => ReturnValue | Promise<ReturnValue>\n  ): Awaitable<this, ReturnValue>;\n  perform<ReturnValue>(\n    callback: (this: NightwatchAPI, client: NightwatchAPI, done: (result?: ReturnValue) => void) => void\n  ): Awaitable<this, ReturnValue>;\n  perform<ReturnValue>(\n    callback: (this: NightwatchAPI, done: (result?: ReturnValue) => void) => void\n  ): Awaitable<this, ReturnValue>;\n\n  /**\n   * Resizes the current window.\n   *\n   * @example\n   *  this.demoTest = function () {\n   *    browser.resizeWindow(1000, 800);\n   *  };\n   *\n   * @see https://nightwatchjs.org/api/resizeWindow.html\n   *\n   * @deprecated In favour of `.window.resize()`.\n   */\n  resizeWindow(\n    width: number,\n    height: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Take a screenshot of the current page and saves it as the given filename.\n   *\n   * @example\n   *  this.demoTest = function (  ) {\n   *    browser.saveScreenshot('/path/to/fileName.png');\n   *  };\n   *\n   * @see https://nightwatchjs.org/api/saveScreenshot.html\n   */\n  saveScreenshot(\n    fileName: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Set a cookie, specified as a cookie JSON object, as defined [here](https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object).\n   *\n   * Uses `cookie` protocol command.\n   *\n   * @example\n   * this.demoTest = function() {\n   *   browser.setCookie({\n   *     name     : \"test_cookie\",\n   *     value    : \"test_value\",\n   *     path     : \"/\", (Optional)\n   *     domain   : \"example.org\", (Optional)\n   *     secure   : false, (Optional)\n   *     httpOnly : false, // (Optional)\n   *     expiry   : 1395002765 // (Optional) time in seconds since midnight, January 1, 1970 UTC\n   *   });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/setCookie.html\n   *\n   * @deprecated In favour of `.cookies.set()`.\n   */\n  setCookie(\n    cookie: Cookie,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Sets the current window position.\n   *\n   * @example\n   *  this.demoTest = function () {\n   *    browser.setWindowPosition(0, 0);\n   *  };\n   *\n   * @see https://nightwatchjs.org/api/setWindowPosition.html\n   *\n   * @deprecated In favour of `.window.setPosition()`.\n   */\n  setWindowPosition(\n    offsetX: number,\n    offsetY: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Change the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect). This is defined as a dictionary of the `screenX`, `screenY`, `outerWidth` and `outerHeight` attributes of the window.\n   *\n   * Its JSON representation is the following:\n   * - `x` - window's screenX attribute;\n   * - `y` - window's screenY attribute;\n   * - `width` - outerWidth attribute;\n   * - `height` - outerHeight attribute.\n   *\n   * All attributes are in in CSS pixels. To change the window react, you can either specify `width` and `height`, `x` and `y` or all properties together.\n   *\n   * @example\n   * module.exports = {\n   *   'demo test .setWindowRect()': function() {\n   *\n   *      // Change the screenX and screenY attributes of the window rect.\n   *      browser.setWindowRect({x: 500, y: 500});\n   *\n   *      // Change the width and height attributes of the window rect.\n   *      browser.setWindowRect({width: 600, height: 300});\n   *\n   *      // Retrieve the attributes\n   *      browser.setWindowRect(function(result) {\n   *        console.log(result.value);\n   *      });\n   *   },\n   *\n   *   'setWindowRect ES6 demo test': async function() {\n   *      await browser.setWindowRect({\n   *        width: 600,\n   *        height: 300,\n   *        x: 100,\n   *        y: 100\n   *      });\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/setWindowRect.html\n   *\n   * @deprecated In favour of `.window.setRect()`.\n   */\n  setWindowRect(\n    options: WindowSizeAndPosition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Sets the current window position.\n   *\n   * @example\n   *  this.demoTest = function () {\n   *    browser.setWindowPosition(0, 0);\n   *  };\n   *\n   * @see https://nightwatchjs.org/api/setWindowSize.html\n   *\n   * @deprecated In favour of `.window.setSize()`.\n   */\n  setWindowSize(\n    width: number,\n    height: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Change or get the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect).\n   * This is defined as a dictionary of the `screenX`, `screenY`, `outerWidth` and `outerHeight` attributes of the window.\n   *\n   * Its JSON representation is the following:\n   * - `x` - window's screenX attribute;\n   * - `y` - window's screenY attribute;\n   * - `width` - outerWidth attribute;\n   * - `height` - outerHeight attribute.\n   *\n   * All attributes are in in CSS pixels. To change the window react, you can either specify `width` and `height`, `x` and `y` or all properties together.\n   *\n   * @example\n   * module.exports = {\n   *   'demo test .getWindowRect()': function() {\n   *      // Retrieve the attributes\n   *      browser.getWindowRect(function(value) {\n   *        console.log(value);\n   *      });\n   *   },\n   *\n   *   'getWindowRect ES6 demo test': async function() {\n   *      const resultValue = await browser.getWindowRect();\n   *      console.log('result value', resultValue);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getWindowRect.html\n   *\n   * @deprecated In favour of `.window.getRect()`.\n   */\n  getWindowRect(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<WindowSizeAndPosition>\n    ) => void\n  ): Awaitable<this, WindowSizeAndPosition>;\n\n  /**\n   * Retrieves the current window size.\n   *\n   * For clients which are compatible with the [W3C Webdriver API](https://w3c.github.io/webdriver/), `getWindowSize` is an alias of `getWindowRect`.\n   *\n   * The `getWindowRect` command returns both dimensions and position of the window, using the `windowRect` protocol command.\n   *\n   * @example\n   * module.exports = {\n   *   'demo test .getWindowSize()': function() {\n   *      // Retrieve the attributes\n   *      browser.getWindowSize(function(value) {\n   *        console.log(value);\n   *      });\n   *   },\n   *\n   *   'getWindowSize ES6 demo test': async function(browser) {\n   *      const value = await browser.getWindowSize();\n   *      console.log('value', value);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getWindowSize.html\n   *\n   * @deprecated In favour of `.window.getRect()`.\n   */\n  getWindowSize(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<WindowSizeAndPosition>\n    ) => void\n  ): Awaitable<this, WindowSizeAndPosition>;\n\n  /**\n   * Retrieves the current window position.\n   *\n   * For clients which are compatible with the [W3C Webdriver API](https://w3c.github.io/webdriver/), `getWindowPosition` is an alias of `getWindowRect`.\n   *\n   * The `getWindowRect` command returns both dimensions and position of the window, using the `windowRect` protocol command.\n   *\n   * @example\n   * module.exports = {\n   *   'demo test .getWindowPosition()': function(browser) {\n   *      // Retrieve the attributes\n   *      browser.getWindowPosition(function(value) {\n   *        console.log(value);\n   *      });\n   *   },\n   *\n   *   'getWindowPosition ES6 demo test': async function(browser) {\n   *      const value = await browser.getWindowPosition();\n   *      console.log('value', value);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getWindowPosition.html\n   *\n   * @deprecated In favour of `.window.getPosition()`.\n   */\n  getWindowPosition(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<WindowPosition>\n    ) => void\n  ): Awaitable<this, WindowPosition>;\n\n  /**\n   * Returns the page source. Uses pageSource protocol command.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.pageSource(function(pageSource) {\n   *      console.log(pageSource);\n   *    });\n   *  };\n   *\n   * @see https://nightwatchjs.org/api/pageSource.html\n   *\n   * @deprecated In favour of `.document.pageSource()`.\n   */\n  pageSource(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Convenience command that adds the specified hash (i.e. url fragment) to the current value of the `launch_url` as set in `nightwatch.json`.\n   *\n   * @example\n   * this.demoTest = function () {\n   *   browser.urlHash('#hashvalue');\n   *   // or\n   *   browser.urlHash('hashvalue');\n   * };\n   *\n   * @see https://nightwatchjs.org/api/urlHash.html\n   */\n  urlHash(\n    hash: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Sets the locate strategy for selectors to `css selector`, therefore every following selector needs to be specified as css.\n   *\n   * @example\n   * this.demoTest = function () {\n   *   browser\n   *     .useCss() // we're back to CSS now\n   *     .setValue('input[type=text]', 'nightwatch');\n   * };\n   *\n   * @see https://nightwatchjs.org/api/useCss.html\n   */\n  useCss(callback?: (this: NightwatchAPI) => void): Awaitable<this, undefined>;\n\n  /**\n   * Sets the locate strategy for selectors to xpath, therefore every following selector needs to be specified as xpath.\n   *\n   * @example\n   * this.demoTest = function () {\n   *   browser\n   *     .useXpath() // every selector now must be xpath\n   *     .click(\"//tr[@data-recordid]/span[text()='Search Text']\");\n   * };\n   *\n   * @see https://nightwatchjs.org/api/useXpath.html\n   */\n  useXpath(\n    callback?: (this: NightwatchAPI) => void\n  ): Awaitable<this, undefined>;\n\n  /**\n   * Injects the [axe-core](https://github.com/dequelabs/axe-core) js library into the current page (using the `.executeScript()` command).\n   * To be paired with `.axeRun()` to evaluate the axe-core accessibility rules.\n   *\n   * @example\n   * describe('accessibility testing', function () {\n   *   it('accessibility rule subset', function (browser) {\n   *     browser\n   *       .url('https://www.w3.org/WAI/demos/bad/after/home.html')\n   *       .assert.titleEquals('Welcome to CityLights! [Accessible Home Page]')\n   *       .axeInject()\n   *       .axeRun('body', {\n   *         runOnly: ['color-contrast', 'image-alt'],\n   *       });\n   *   });\n   * });\n   *\n   * @see https://nightwatchjs.org/api/axeInject.html\n   */\n  axeInject(): Awaitable<this, null>;\n\n  /**\n   * Analyzes the current page against applied axe rules.\n   *\n   * @example\n   * describe('accessibility testing', function () {\n   *   it('accessibility rule subset', function (browser) {\n   *     browser\n   *       .url('https://www.w3.org/WAI/demos/bad/after/home.html')\n   *       .assert.titleEquals('Welcome to CityLights! [Accessible Home Page]')\n   *       .axeInject()\n   *       .axeRun('body', {\n   *         runOnly: ['color-contrast', 'image-alt'],\n   *       });\n   *   });\n   *\n   *   it('accessibility rule subset 2', function (browser) {\n   *     browser\n   *       .url('https://nightwatchjs.org')\n   *       .axeInject()\n   *       .axeRun(['#navBar', 'nav'], {\n   *         rules: {\n   *           'color-contrast': { enabled: false },\n   *         }\n   *       });\n   *   });\n   * });\n   *\n   * @param context - Defines the scope of the analysis, will cascade to child elements. See\n   * [axe-core docs](https://github.com/dequelabs/axe-core/blob/master/doc/API.md#context-parameter) for more details.\n   * @param options - Allows configuration of what rules will be run (accessibility standard or rules to enable/disable).\n   * See [axe-core docs](https://www.deque.com/axe/core-documentation/api-documentation/#options-parameter) for more details.\n   * @param callback - Optional callback function which is called with the results.\n   *\n   * @see {@link https://nightwatchjs.org/api/axeRun.html}\n   * @see {@link https://github.com/dequelabs/axe-core/blob/master/doc/API.md#api-name-axerun}\n   */\n  axeRun(\n    context?: unknown,\n    options?: { [key: string]: any },\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<{ [key: string]: any }>\n    ) => void\n  ): Awaitable<this, { [key: string]: any }>;\n}\n\nexport interface ClientCommands extends ChromiumClientCommands, SharedClientCommands {\n  /**\n   * Close the current window. This can be useful when you're working with multiple windows open (e.g. an OAuth login).\n   * Uses `window` protocol command.\n   *\n   * @example\n   * describe('closeWindow command demo' , function (result) {\n   *   test('demo test', function () {\n   *     browser.closeWindow();\n   *   });\n   * });\n   * @see https://nightwatchjs.org/api/closeWindow.html\n   *\n   * @deprecated In favour of `.window.close()`.\n   */\n  closeWindow(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Sets the current window state to fullscreen.\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test': function(browser) {\n   *     browser.fullscreenWindow(function(result) {\n   *       console.log(result);\n   *     });\n   *   },\n   *\n   *   'ES6 async demo Test': async function(browser) {\n   *     const result = await browser.fullscreenWindow();\n   *     console.log('result value is:', result.value);\n   *   }\n   * }\n   * @see https://nightwatchjs.org/api/fullscreenWindow.html\n   *\n   * @deprecated In favour of `.window.fullscreen()`.\n   */\n  fullscreenWindow(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Hides the window in the system tray. If the window happens to be in fullscreen mode,\n   * it is restored the normal state then it will be \"iconified\" - minimize or hide the window from the visible screen.\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test': function(browser) {\n   *     browser.minimizeWindow(function(result) {\n   *       console.log(result);\n   *     });\n   *   },\n   *\n   *   'ES6 async demo Test': async function(browser) {\n   *     const result = await browser.minimizeWindow();\n   *     console.log('result value is:', result.value);\n   *   }\n   * }\n   * @see https://nightwatchjs.org/api/minimizeWindow.html\n   *\n   * @deprecated In favour of `.window.minimize()`.\n   */\n  minimizeWindow(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Opens a new top-level browser window, which can be either a tab (default) or a separate new window.\n   *\n   * This command is only available for W3C Webdriver compatible browsers.\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test': function(browser) {\n   *     // open a new window tab (default)\n   *     browser.openNewWindow(function(result) {\n   *       console.log(result);\n   *     });\n   *\n   *     // open a new window\n   *     browser.openNewWindow('window', function(result) {\n   *       console.log(result);\n   *     });\n   *   },\n   *\n   *   'ES6 async demo Test': async function(browser) {\n   *     const result = await browser.openNewWindow();\n   *     console.log('result value is:', result.value);\n   *   }\n   * }\n   * @see https://nightwatchjs.org/api/openNewWindow.html\n   *\n   * @deprecated In favour of `.window.open()`.\n   */\n  openNewWindow(\n    type?: WindowType,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Retrieve the URL of the current page.\n   *\n   * @example\n   * describe('Navigation commands demo', function() {\n   *   test('demoTest', function(browser) {\n   *     // navigate to new url:\n   *     browser.navigateTo('https://nightwatchjs.org');\n   *\n   *     // Retrieve to url with callback:\n   *     browser.getCurrentUrl(function(result) {\n   *       console.log(result.value);\n   *     });\n   *   });\n   *\n   *   test('demoTestAsync', async function(browser) {\n   *     const currentUrl = await browser.navigateTo('https://nightwatchjs.org').getCurrentUrl();\n   *     console.log('currentUrl:', currentUrl); // will print 'https://nightwatchjs.org'\n   *   });\n   *\n   * });\n   *\n   *  @see https://nightwatchjs.org/api/getCurrentUrl.html\n   */\n  getCurrentUrl(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Navigate to a new URL. This method will also call the `onBrowserNavigate()` test global,\n   * right after the page is loaded.\n   *\n   * @example\n   *  describe('Navigation commands demo', function() {\n   *    test('demoTest', function(browser) {\n   *      // navigate to new url:\n   *      browser.navigateTo('https://nightwatchjs.org');\n   *\n   *      // Retrieve to url with callback:\n   *      browser.getCurrentUrl(function(result) {\n   *        console.log(result.value);\n   *      });\n   *    });\n   *\n   *    test('demoTestAsync', async function(browser) {\n   *      const currentUrl = await browser.navigateTo('https://nightwatchjs.org').getCurrentUrl();\n   *      console.log('currentUrl:', currentUrl); // will print 'https://nightwatchjs.org'\n   *    });\n   *  });\n   *\n   *  @see https://nightwatchjs.org/api/navigateTo.html\n   */\n  navigateTo(\n    url: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Ends the session and closes down the test WebDriver server, if one is running.\n   * This is similar to calling the .end() command, but the former doesn't quit the WebDriver session.\n   *\n   * This command will also execute the `onBrowserQuit()` global, if one is defined.\n   *\n   * @example\n   * this.demoTest = function (browser) {\n   *   browser.quit(function(result) {\n   *     console.log(result.value);\n   *   });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/quit.html\n   */\n  quit(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Waits for a condition to evaluate to a \"truthy\" value. The condition may be specified by any function which\n   * returns the value to be evaluated or a Promise to wait for.\n   *\n   * An optional wait time can be specified, otherwise the global waitForConditionTimeout value will be used.\n   *\n   * @example\n   * describe('waitUntil Example', function() {\n   *   it('demo Test', function(browser) {\n   *     browser\n   *       .url('https://nightwatchjs.org')\n   *       .waitUntil(async function() {\n   *         const title = await this.execute(function() {\n   *           return document.title;\n   *         });\n   *\n   *         return title === 'Nightwatch.js';\n   *       }, 1000);\n   *   });\n   * });\n   */\n  waitUntil(\n    conditionFn: (this: NightwatchAPI) => void,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<this, null>;\n  waitUntil(\n    conditionFn: (this: NightwatchAPI) => void,\n    waitTimeMs: number,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<this, null>;\n  waitUntil(\n    conditionFn: (this: NightwatchAPI) => void,\n    waitTimeMs: number,\n    retryInterval: number,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<this, null>;\n  waitUntil(\n    conditionFn: (this: NightwatchAPI) => void,\n    waitTimeMs: number,\n    retryInterval: number,\n    message: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<this, null>;\n\n  /**\n   * Change focus to another window. The window to change focus to may be specified by its server assigned window handle, or by the value of its name attribute.\n   *\n   * To find out the window handle use `windowHandles` command\n   *\n   * @example\n   *  this.demoTest = function () {\n   *    browser.windowHandles(function(result) {\n   *      const handle = result.value[0];\n   *      browser.switchWindow(handle);\n   *    });\n   *  };\n   *\n   *  this.demoTestAsync = async function () {\n   *    const result = await browser.windowHandles();\n   *    const handle = result[0];\n   *    browser.switchWindow(handle);\n   *  };\n   *\n   * @alias switchToWindow\n   *\n   * @see https://nightwatchjs.org/api/switchWindow.html\n   *\n   * @deprecated In favour of `.window.switch()`.\n   */\n  switchWindow(\n    handleOrName: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Change focus to another window. The window to change focus to may be specified by its server assigned window handle, or by the value of its name attribute.\n   *\n   * To find out the window handle use `windowHandles` command\n   *\n   * @example\n   *  this.demoTest = function () {\n   *    browser.windowHandles(function(result) {\n   *      const handle = result.value[0];\n   *      browser.switchToWindow(handle);\n   *    });\n   *  };\n   *\n   *  this.demoTestAsync = async function () {\n   *    const result = await browser.windowHandles();\n   *    const handle = result[0];\n   *    browser.switchToWindow(handle);\n   *  };\n   *\n   * @see https://nightwatchjs.org/api/switchToWindow.html\n   *\n   * @deprecated In favour of `.window.switchTo()`.\n   */\n  switchToWindow(\n    handleOrName: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n}\n\nexport interface ElementCommands {\n  /**\n   * Will check, click, on an unchecked checkbox or radio input if not already checked.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest(browser) {\n   *     browser.check('input[type=checkbox]:not(:checked)');\n   *\n   *     browser.check('input[type=checkbox]:not(:checked)', function(result) {\n   *       console.log('Check result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.check('css selector', 'input[type=checkbox]:not(:checked)');\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide#element-properties\n   *     browser.check({\n   *       selector: 'input[type=checkbox]:not(:checked)',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     });\n   *\n   *     browser.check({\n   *       selector: 'input[type=checkbox]:not(:checked)',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.check('input[type=checkbox]:not(:checked)');\n   *     console.log('Check result', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/check.html\n   */\n  check(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  check(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  /**\n   * Clear a textarea or a text input element's value.\n   * Starting with v1.1 `clearValue()` will wait for the element to be present (until the specified timeout).\n   *\n   * If the element is not found, an error is thrown which will cause the test to fail.\n   * Starting with `v1.2` you can suppress element not found errors by specifying the `suppressNotFoundErrors` flag.\n   *\n   * @example\n   *   describe('clearValue Command demo', function() {\n   *     test('demo test', function() {\n   *       browser.clearValue('#login input[type=text]');\n   *\n   *       browser.clearValue('#login input[type=text]', function(result) {\n   *         console.log('clearValue result', result);\n   *       });\n   *\n   *       // with explicit locate strategy\n   *       browser.clearValue('css selector', '#login input[type=text]');\n   *\n   *       // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *       browser.clearValue({\n   *         selector: '#login input[type=text]',\n   *         index: 1,\n   *         suppressNotFoundErrors: true\n   *       });\n   *\n   *       browser.clearValue({\n   *         selector: '#login input[type=text]',\n   *         timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *       });\n   *\n   *     });\n   *\n   *   });\n   *\n   * @see https://nightwatchjs.org/api/clearValue.html\n   */\n  clearValue(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  clearValue(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Simulates a click event on the given DOM element.\n   * The element is scrolled into view if it is not already pointer-interactable.\n   * See the WebDriver specification for <a href=\"https://www.w3.org/TR/webdriver/#element-interactability\" target=\"_blank\">element interactability</a>.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.click('#main ul li a.first');\n   *\n   *     browser.click('#main ul li a.first', function(result) {\n   *       console.log('Click result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.click('css selector', '#main ul li a.first');\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.click({\n   *       selector: '#main ul li a',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     });\n   *\n   *     browser.click({\n   *       selector: '#main ul li a.first',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.click('#main ul li a.first');\n   *     console.log('Click result', result);\n   *   }\n   * }\n   *\n   *\n   * @see https://nightwatchjs.org/api/click.html\n   */\n  click(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  click(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Move to the element and click (without releasing) in the middle of the given element.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.clickAndHold('#main ul li a.first');\n   *\n   *     browser.clickAndHold('#main ul li a.first', function(result) {\n   *       console.log('Click result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.clickAndHold('css selector', '#main ul li a.first');\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.clickAndHold({\n   *       selector: '#main ul li a',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     });\n   *\n   *     browser.clickAndHold({\n   *       selector: '#main ul li a.first',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function() {\n   *     const result = await browser.clickAndHold('#main ul li a.first');\n   *     console.log('Right click result', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/clickAndHold.html#apimethod-container\n   */\n  clickAndHold(\n    selector: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  clickAndHold(\n    using: LocateStrategy,\n    selector: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Move to the element and peforms a double-click in the middle of the element.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.doubleClick('#main ul li a.first');\n   *\n   *     browser.doubleClick('#main ul li a.first', function(result) {\n   *       console.log('double click result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.doubleClick('css selector', '#main ul li a.first');\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.doubleClick({\n   *       selector: '#main ul li a',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     });\n   *\n   *     browser.doubleClick({\n   *       selector: '#main ul li a.first',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function() {\n   *     const result = await browser.doubleClick('#main ul li a.first');\n   *     console.log('double click result', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/doubleClick.html#apimethod-container\n   */\n  doubleClick(\n    selector: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  doubleClick(\n    using: LocateStrategy,\n    selector: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Retrieve the value of an attribute for a given DOM element.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.getAttribute('#main ul li a.first', 'href', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getAttribute('css selector', '#main ul li a.first', 'href', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getAttribute({\n   *       selector: '#main ul li a.first',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     }, 'href', function(result) {\n   *       console.log('result', result);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.getAttribute('#main ul li a.first', 'href');\n   *     console.log('attribute', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getAttribute.html\n   */\n  getAttribute(\n    selector: Definition,\n    attribute: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string | null>\n    ) => void\n  ): Awaitable<this, string | null>;\n  getAttribute(\n    using: LocateStrategy,\n    selector: Definition,\n    attribute: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string | null>\n    ) => void\n  ): Awaitable<this, string | null>;\n\n  /**\n   * Retrieve the value of a css property for a given DOM element.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.getCssProperty('#main ul li a.first', 'display', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getCssProperty('css selector', '#main ul li a.first', 'display', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getCssProperty({\n   *       selector: '#main ul li a.first',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     }, 'display', function(result) {\n   *       console.log('result', result);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.getCssProperty('#main ul li a.first', 'display');\n   *     console.log('display', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getCssProperty.html\n   */\n  getCssProperty(\n    selector: Definition,\n    cssProperty: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n  getCssProperty(\n    using: LocateStrategy,\n    selector: Definition,\n    cssProperty: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Determine an element's size in pixels. For W3C Webdriver compatible clients (such as GeckoDriver), this command is equivalent to `getLocation` and both return\n   * the dimensions and coordinates of the given element:\n   * - x: X axis position of the top-left corner of the element, in CSS pixels\n   * - y: Y axis position of the top-left corner of the element, in CSS pixels\n   * - height: Height of the element’s bounding rectangle in CSS pixels;\n   * - width: Width of the web element’s bounding rectangle in CSS pixels.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.getElementSize('#login', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getElementSize('css selector', '#login', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getElementSize({\n   *       selector: '#login',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     }, function(result) {\n   *       console.log('result', result);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.getElementSize('#login');\n   *     console.log('classList', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getElementSize.html\n   */\n  getElementSize(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchSizeAndPosition>\n    ) => void\n  ): Awaitable<this, NightwatchSizeAndPosition>;\n  getElementSize(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchSizeAndPosition>\n    ) => void\n  ): Awaitable<this, NightwatchSizeAndPosition>;\n\n  /**\n   * Determine an element's location on the page. The point (0, 0) refers to the upper-left corner of the page. The element's coordinates are returned as a JSON object with x and y properties.\n   *\n   * For W3C Webdriver compatible clients (such as GeckoDriver), this command is equivalent to `getElementSize` and both return\n   * the dimensions and coordinates of the given element:\n   * - x: X axis position of the top-left corner of the element, in CSS pixels\n   * - y: Y axis position of the top-left corner of the element, in CSS pixels\n   * - height: Height of the element’s bounding rectangle in CSS pixels;\n   * - width: Width of the web element’s bounding rectangle in CSS pixels.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.getLocation('#login', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getLocation('css selector', '#login', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getLocation({\n   *       selector: '#login',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     }, function(result) {\n   *       console.log('result', result);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.getLocation('#login');\n   *     console.log('location', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getLocation.html\n   */\n  getLocation(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchSizeAndPosition>\n    ) => void\n  ): Awaitable<this, NightwatchSizeAndPosition>;\n  getLocation(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchSizeAndPosition>\n    ) => void\n  ): Awaitable<this, NightwatchSizeAndPosition>;\n\n  /**\n   * Determine an element's location on the screen once it has been scrolled into view.\n   *\n   * @example\n   * this.demoTest = function () {\n   *   browser.getLocationInView(\"#main ul li a.first\", function(result) {\n   *     this.assert.equal(typeof result, \"object\");\n   *     this.assert.equal(result.status, 0);\n   *     this.assert.equal(result.value.x, 200);\n   *     this.assert.equal(result.value.y, 200);\n   *   });\n   * };\n   *\n   * @see https://nightwatchjs.org/api/getLocationInView.html\n   *\n   * @deprecated This is JSON Wire Protocol command and is no longer supported.\n   */\n  getLocationInView(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchPosition>\n    ) => void\n  ): Awaitable<this, NightwatchPosition>;\n  getLocationInView(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchPosition>\n    ) => void\n  ): Awaitable<this, NightwatchPosition>;\n\n  /**\n   * Query for an element's tag name.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.getTagName('#login', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getTagName('css selector', '#login', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getTagName({\n   *       selector: '#login',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     }, function(result) {\n   *       console.log('result', result);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.getTagName('#login');\n   *     console.log('tagName', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getTagName.html\n   */\n  getTagName(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n  getTagName(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Returns the visible text for the element.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.getText('#main ul li a.first', function(result) {\n   *       this.assert.equal(typeof result, 'object);\n   *       this.assert.strictEqual(result.status, 0); // only when using Selenium / JSONWire\n   *       this.assert.equal(result.value, 'nightwatchjs.org');\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getText('css selector', '#main ul li a.first', function(result) {\n   *       console.log('getText result', result.value);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getText({\n   *       selector: '#main ul li a',\n   *       index: 1\n   *     }, function(result) {\n   *       console.log('getText result', result.value);\n   *     });\n   *\n   *     browser.getText({\n   *       selector: '#main ul li a.first',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     }, function(result) {\n   *       console.log('getText result', result.value);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function() {\n   *     const result = await browser.getText('#main ul li a.first');\n   *     console.log('getText result', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getText.html\n   */\n  getText(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n  getText(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Returns a form element current value.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.getValue('#login input[type=text]', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getValue('css selector', '#login input[type=text]', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getValue({\n   *       selector: '#login input[type=text]',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     }, function(result) {\n   *       console.log('result', result);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function() {\n   *     const result = await browser.getValue('#login input[type=text]');\n   *     console.log('Value', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getValue.html\n   */\n  getValue(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n  getValue(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Determine if an element is currently displayed.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.isVisible('#main ul li a.first', function(result) {\n   *       this.assert.equal(typeof result, \"object\");\n   *       this.assert.equal(result.status, 0);\n   *       this.assert.equal(result.value, true);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.isVisible('css selector', '#main ul li a.first');\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.isVisible({\n   *       selector: '#main ul li a',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     });\n   *\n   *     browser.isVisible({\n   *       selector: '#main ul li a.first',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function() {\n   *     const result = await browser.isVisible('#main ul li a.first');\n   *     console.log('isVisible result', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/isVisible.html\n   */\n  isVisible(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n  isVisible(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   * Determines if an element is present in the DOM.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest(browser) {\n   *     browser.isPresent('#main ul li a.first', function(result) {\n   *       this.assert.equal(typeof result, \"object\");\n   *       this.assert.equal(result.status, 0);\n   *       this.assert.equal(result.value, true);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.isPresent('css selector', '#main ul li a.first');\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.isPresent({\n   *       selector: '#main ul li a',\n   *       index: 1,\n   *     });\n   *\n   *     browser.isPresent({\n   *       selector: '#main ul li a.first',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.isPresent('#main ul li a.first');\n   *     console.log('isPresent result', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/isPresent.html\n   */\n  isPresent(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n  isPresent(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   * Move the mouse by an offset of the specified element. If an element is provided but no offset, the mouse will be moved to the center of the element.\n   * If the element is not visible, it will be scrolled into view.\n   *\n   * @example\n   * this.demoTest = function () {\n   *   browser.moveToElement('#main', 10, 10);\n   * };\n   *\n   * @see https://nightwatchjs.org/api/moveToElement.html\n   */\n  moveToElement(\n    selector: Definition,\n    xoffset: number,\n    yoffset: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  moveToElement(\n    using: LocateStrategy,\n    selector: Definition,\n    xoffset: number,\n    yoffset: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Simulates a context-click(right click) event on the given DOM element.\n   * The element is scrolled into view if it is not already pointer-interactable.\n   * See the WebDriver specification for element [interactability](https://www.w3.org/TR/webdriver/#element-interactability).\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.rightClick('#main ul li a.first');\n   *\n   *     browser.rightClick('#main ul li a.first', function(result) {\n   *       console.log('Click result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.rightClick('css selector', '#main ul li a.first');\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.rightClick({\n   *       selector: '#main ul li a',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     });\n   *\n   *     browser.rightClick({\n   *       selector: '#main ul li a.first',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function() {\n   *     const result = await browser.rightClick('#main ul li a.first');\n   *     console.log('Right click result', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/rightClick.html#apimethod-container\n   */\n  rightClick(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  rightClick(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Sends some text to an element. Can be used to set the value of a form element or to send a sequence of key strokes to an element. Any UTF-8 character may be specified.\n   *\n   * From Nightwatch v2, **setValue** also clears the existing value of the element by calling the **clearValue()** beforehand.\n   *\n   * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types),\n   * is loaded onto the main Nightwatch instance as `browser.Keys`.\n   *\n   * @example\n   * // send some simple text to an input\n   * this.demoTest = function () {\n   *   browser.setValue('input[type=text]', 'nightwatch');\n   * };\n   * //\n   * // send some text to an input and hit enter.\n   * this.demoTest = function () {\n   *   browser.setValue('input[type=text]', ['nightwatch', browser.Keys.ENTER]);\n   * };\n   *\n   * @see https://nightwatchjs.org/api/setValue.html\n   */\n  setValue(\n    selector: Definition,\n    inputValue: string | string[],\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  setValue(\n    using: LocateStrategy,\n    selector: Definition,\n    inputValue: string | string[],\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Types a key sequence on the DOM element. Can be used to send a sequence of key strokes to an element.\n   * Any UTF-8 character may be specified.\n   *\n   * **sendKeys** does not clear the existing value of the element. To do so, use **setValue()** instead.\n   *\n   * An object map with available keys and their respective UTF-8 characters,\n   * as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types),\n   * is loaded onto the main Nightwatch instance as `browser.Keys`.\n   *\n   * @example\n   * // send some simple text to an input\n   * this.demoTest = function () {\n   *   browser.sendKeys('input[type=text]', 'nightwatch');\n   * };\n   * //\n   * // send some text to an input and hit enter.\n   * this.demoTest = function () {\n   *   browser.sendKeys('input[type=text]', ['nightwatch', browser.Keys.ENTER]);\n   * };\n   *\n   * @see https://nightwatchjs.org/api/sendKeys.html\n   */\n  sendKeys(\n    selector: Definition,\n    inputValue: string | string[],\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  sendKeys(\n    using: LocateStrategy,\n    selector: Definition,\n    inputValue: string | string[],\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Submit a FORM element. The submit command may also be applied to any element that is a descendant of a FORM element. Uses `submit` protocol command.\n   *\n   * @example\n   * this.demoTest = function () {\n   *   browser.submitForm('form.login');\n   * };\n   *\n   * @see https://nightwatchjs.org/api/submitForm.html\n   */\n  submitForm(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  submitForm(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Opposite of `waitForElementPresent`. Waits a given time in milliseconds (default 5000ms)\n   * for an element to be not present (i.e. removed) in the page before performing\n   * any other commands or assertions.\n   * If the element is still present after the specified amount of time, the test fails.\n   *\n   * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file.\n   * Similarly, a default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds).\n   *\n   * @returns `null` if element not found, `Error` otherwise.\n   *\n   * @example\n   * // 'message' should always be the last argument (if provided).\n   * // 'callback' should only be second-last to the 'message' argument, otherwise always last.\n   * module.exports = {\n   *  'demo Test': function() {\n   *     // with default implicit timeout of 5000ms (can be overwritten in settings under 'globals.waitForConditionTimeout')\n   *     browser.waitForElementNotPresent('#dialog');\n   *\n   *     // specify the locate strategy (css selector/xpath) as the first argument\n   *     browser.waitForElementNotPresent('css selector', '#dialog');\n   *\n   *     // with explicit timeout (in milliseconds)\n   *     browser.waitForElementNotPresent('#dialog', 1000);\n   *\n   *     // continue if failed\n   *     browser.waitForElementNotPresent('#dialog', 1000, false);\n   *\n   *     // with callback\n   *     browser.waitForElementNotPresent('#dialog', 1000, function() {\n   *       // do something while we're here\n   *     });\n   *\n   *     // with custom output message - the locate strategy is required\n   *     browser.waitForElementNotPresent('css selector', '#dialog', 'The dialog container is removed.');\n   *\n   *     // with custom Spanish message\n   *     browser.waitForElementNotPresent('#dialog', 1000, 'elemento %s no era presente en %d ms');\n   *\n   *     // many combinations possible - the message is always the last argument\n   *     browser.waitForElementNotPresent('#dialog', 1000, false, function() {}, 'elemento %s no era presente en %d ms');\n   *   },\n   *\n   *   'demo Test with selector objects': function() {\n   *      browser.waitForElementNotPresent({\n   *        selector: '#dialog',\n   *        timeout: 1000\n   *      });\n   *\n   *      browser.waitForElementNotPresent({\n   *        selector: '#dialog',\n   *        locateStrategy: 'css selector'\n   *      }, 'Custom output message');\n   *\n   *      browser.waitForElementNotPresent({\n   *        selector: '.container',\n   *        index: 2,\n   *        retryInterval: 100,\n   *        abortOnFailure: true\n   *      });\n   *   }\n   *\n   *   'page object demo Test': function () {\n   *      var nightwatch = browser.page.nightwatch();\n   *      nightwatch\n   *        .navigate()\n   *        .assert.titleContains('Nightwatch.js');\n   *\n   *      nightwatch.waitForElementNotPresent('@dialogContainer', function(result) {\n   *        console.log(result);\n   *      });\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/waitForElementNotPresent.html\n   * @since v0.4.0\n   */\n  waitForElementNotPresent(\n    selector: Definition,\n    timeoutOrCallbackOrMessage?: number | NightwatchGenericCallback<null | ElementResult[]> | string,\n    pollIntervalOrAbortOnFailureOrCallbackOrMessage?: number | boolean | NightwatchGenericCallback<null | ElementResult[]> | string,\n    abortOnFailureOrCallbackOrMessage?: boolean | NightwatchGenericCallback<null | ElementResult[]> | string,\n    callbackOrMessage?: NightwatchGenericCallback<null | ElementResult[]> | string,\n    message?: string\n  ): Awaitable<this, null | Error>;\n  waitForElementNotPresent(\n    using: LocateStrategy,\n    selector: Definition,\n    timeoutOrCallbackOrMessage?: number | NightwatchGenericCallback<null | ElementResult[]> | string,\n    pollIntervalOrAbortOnFailureOrCallbackOrMessage?: number | boolean | NightwatchGenericCallback<null | ElementResult[]> | string,\n    abortOnFailureOrCallbackOrMessage?: boolean | NightwatchGenericCallback<null | ElementResult[]> | string,\n    callbackOrMessage?: NightwatchGenericCallback<null | ElementResult[]> | string,\n    message?: string\n  ): Awaitable<this, null | Error>;\n\n  /**\n   * Opposite of `waitForElementVisible`. Waits a given time in milliseconds (default 5000ms)\n   * for an element to be not visible (i.e. hidden but existing) in the page before\n   * performing any other commands or assertions.\n   * If the element fails to be hidden in the specified amount of time, the test fails.\n   *\n   * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file.\n   * Similarly, a default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds).\n   *\n   * @returns `false` if element not visible, `Error` otherwise.\n   *\n   * @example\n   * // 'message' should always be the last argument (if provided).\n   * // 'callback' should only be second-last to the 'message' argument, otherwise always last.\n   * module.exports = {\n   *  'demo Test': function() {\n   *     // with default implicit timeout of 5000ms (can be overwritten in settings under 'globals.waitForConditionTimeout')\n   *     browser.waitForElementNotVisible('#dialog');\n   *\n   *     // specify the locate strategy (css selector/xpath) as the first argument\n   *     browser.waitForElementNotVisible('css selector', '#dialog');\n   *\n   *     // with explicit timeout (in milliseconds)\n   *     browser.waitForElementNotVisible('#dialog', 1000);\n   *\n   *     // continue if failed\n   *     browser.waitForElementNotVisible('#dialog', 1000, false);\n   *\n   *     // with callback\n   *     browser.waitForElementNotVisible('#dialog', 1000, function() {\n   *       // do something while we're here\n   *     });\n   *\n   *     // with custom output message - the locate strategy is required\n   *     browser.waitForElementNotVisible('css selector', '#dialog', 'The dialog container is not visible.');\n   *\n   *     // with custom Spanish message\n   *     browser.waitForElementNotVisible('#dialog', 1000, 'elemento %s no era visible en %d ms');\n   *\n   *     // many combinations possible - the message is always the last argument\n   *     browser.waitForElementNotVisible('#dialog', 1000, false, function() {}, 'elemento %s no era visible en %d ms');\n   *   },\n   *\n   *   'demo Test with selector objects': function() {\n   *      browser.waitForElementNotVisible({\n   *        selector: '#dialog',\n   *        timeout: 1000\n   *      });\n   *\n   *      browser.waitForElementNotVisible({\n   *        selector: '#dialog',\n   *        locateStrategy: 'css selector'\n   *      }, 'Custom output message');\n   *\n   *      browser.waitForElementNotVisible({\n   *        selector: '.container',\n   *        index: 2,\n   *        retryInterval: 100,\n   *        abortOnFailure: true\n   *      });\n   *   }\n   *\n   *   'page object demo Test': function () {\n   *      var nightwatch = browser.page.nightwatch();\n   *      nightwatch\n   *        .navigate()\n   *        .assert.titleContains('Nightwatch.js');\n   *\n   *      nightwatch.waitForElementNotVisible('@mainDialog', function(result) {\n   *        console.log(result);\n   *      });\n   *   }\n   * }\n   *\n   * @since v0.4.0\n   * @see https://nightwatchjs.org/api/waitForElementNotVisible.html\n   */\n  waitForElementNotVisible(\n    selector: Definition,\n    timeoutOrCallbackOrMessage?: number | NightwatchGenericCallback<boolean> | string,\n    pollIntervalOrAbortOnFailureOrCallbackOrMessage?: number | boolean | NightwatchGenericCallback<boolean> | string,\n    abortOnFailureOrCallbackOrMessage?: boolean | NightwatchGenericCallback<boolean> | string,\n    callbackOrMessage?: NightwatchGenericCallback<boolean> | string,\n    message?: string\n  ): Awaitable<this, false | Error>;\n  waitForElementNotVisible(\n    using: LocateStrategy,\n    selector: Definition,\n    timeoutOrCallbackOrMessage?: number | NightwatchGenericCallback<boolean> | string,\n    pollIntervalOrAbortOnFailureOrCallbackOrMessage?: number | boolean | NightwatchGenericCallback<boolean> | string,\n    abortOnFailureOrCallbackOrMessage?: boolean | NightwatchGenericCallback<boolean> | string,\n    callbackOrMessage?: NightwatchGenericCallback<boolean> | string,\n    message?: string\n  ): Awaitable<this, false | Error>;\n\n  /**\n   * Waits a given time in milliseconds (default 5000ms) for an element to be present in the page before performing any other commands or assertions.\n   * If the element fails to be present in the specified amount of time, the test fails. You can change this by setting `abortOnFailure` to `false`.\n   *\n   * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file.\n   * Similarly, the default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds).\n   *\n   * @returns `ElementResult[]` if element is found, `Error` otherwise.\n   *\n   * @example\n   * // 'message' should always be the last argument (if provided).\n   * // 'callback' should only be second-last to the 'message' argument, otherwise always last.\n   * module.exports = {\n   *  'demo Test': function() {\n   *     // with default implicit timeout of 5000ms (can be overwritten in settings under 'globals.waitForConditionTimeout')\n   *     browser.waitForElementPresent('#index-container');\n   *\n   *     // specify the locate strategy (css selector/xpath) as the first argument\n   *     browser.waitForElementPresent('css selector', '#index-container');\n   *\n   *     // with explicit timeout (in milliseconds)\n   *     browser.waitForElementPresent('#index-container', 1000);\n   *\n   *     // continue if failed\n   *     browser.waitForElementPresent('#index-container', 1000, false);\n   *\n   *     // with callback\n   *     browser.waitForElementPresent('#index-container', 1000, function() {\n   *       // do something while we're here\n   *     });\n   *\n   *     // with custom output message - the locate strategy is required\n   *     browser.waitForElementPresent('css selector', '#index-container', 'The index container is found.');\n   *\n   *     // with custom Spanish message\n   *     browser.waitForElementPresent('#index-container', 1000, 'elemento %s no era presente en %d ms');\n   *\n   *     // many combinations possible - the message is always the last argument\n   *     browser.waitForElementPresent('#index-container', 1000, false, function() {}, 'elemento %s no era presente en %d ms');\n   *   },\n   *\n   *   'demo Test with selector objects': function() {\n   *      browser.waitForElementPresent({\n   *        selector: '#index-container',\n   *        timeout: 1000\n   *      });\n   *\n   *      browser.waitForElementPresent({\n   *        selector: '#index-container',\n   *        locateStrategy: 'css selector'\n   *      }, 'Custom output message');\n   *\n   *      browser.waitForElementPresent({\n   *        selector: '.container',\n   *        index: 2,\n   *        retryInterval: 100,\n   *        abortOnFailure: true\n   *      });\n   *   }\n   *\n   *   'page object demo Test': function () {\n   *      var nightwatch = browser.page.nightwatch();\n   *      nightwatch\n   *        .navigate()\n   *        .assert.titleContains('Nightwatch.js');\n   *\n   *      nightwatch.waitForElementPresent('@featuresList', function(result) {\n   *        console.log(result);\n   *      });\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/waitForElementPresent.html\n   */\n  waitForElementPresent(\n    selector: Definition,\n    timeoutOrCallbackOrMessage?: number | NightwatchGenericCallback<null | ElementResult[]> | string,\n    pollIntervalOrAbortOnFailureOrCallbackOrMessage?: number | boolean | NightwatchGenericCallback<null | ElementResult[]> | string,\n    abortOnFailureOrCallbackOrMessage?: boolean | NightwatchGenericCallback<null | ElementResult[]> | string,\n    callbackOrMessage?: NightwatchGenericCallback<null | ElementResult[]> | string,\n    message?: string\n  ): Awaitable<this, ElementResult[] | Error>;\n  waitForElementPresent(\n    using: LocateStrategy,\n    selector: Definition,\n    timeoutOrCallbackOrMessage?: number | NightwatchGenericCallback<null | ElementResult[]> | string,\n    pollIntervalOrAbortOnFailureOrCallbackOrMessage?: number | boolean | NightwatchGenericCallback<null | ElementResult[]> | string,\n    abortOnFailureOrCallbackOrMessage?: boolean | NightwatchGenericCallback<null | ElementResult[]> | string,\n    callbackOrMessage?: NightwatchGenericCallback<null | ElementResult[]> | string,\n    message?: string\n  ): Awaitable<this, ElementResult[] | Error>;\n\n  /**\n   * Waits a given time in milliseconds for an element to be visible in the page before performing any other commands or assertions.\n   *\n   * If the element fails to be present and visible in the specified amount of time, the test fails. You can change this by setting `abortOnFailure` to `false`.\n   *\n   * You can change the polling interval by defining a `waitForConditionPollInterval` property (in milliseconds) in as a global property in your `nightwatch.json` or in your external globals file.\n   *\n   * Similarly, a default timeout can be specified as a global `waitForConditionTimeout` property (in milliseconds).\n   *\n   * @returns `true` is element is visible, `Error` otherwise.\n   *\n   * @example\n   * // 'message' should always be the last argument (if provided).\n   * // 'callback' should only be second-last to the 'message' argument, otherwise always last.\n   * this.demoTest = function (browser) {\n   *   browser.waitForElementVisible('body', 1000);\n   *   // continue if failed\n   *   browser.waitForElementVisible('body', 1000, false);\n   *   // with callback\n   *   browser.waitForElementVisible('body', 1000, function() {\n   *     // do something while we're here\n   *   });\n   *   // custom Spanish message\n   *   browser.waitForElementVisible('body', 1000, 'elemento %s no era visible en %d ms');\n   *   // many combinations possible - the message is always the last argument\n   *   browser.waitForElementVisible('body', 1000, false, function() {}, 'elemento %s no era visible en %d ms');\n   * };\n   *\n   * @see https://nightwatchjs.org/api/waitForElementVisible.html\n   */\n  waitForElementVisible(\n    selector: Definition,\n    timeoutOrCallbackOrMessage?: number | NightwatchGenericCallback<boolean> | string,\n    pollIntervalOrAbortOnFailureOrCallbackOrMessage?: number | boolean | NightwatchGenericCallback<boolean> | string,\n    abortOnFailureOrCallbackOrMessage?: boolean | NightwatchGenericCallback<boolean> | string,\n    callbackOrMessage?: NightwatchGenericCallback<boolean> | string,\n    message?: string\n  ): Awaitable<this, true | Error>;\n\n  waitForElementVisible(\n    using: LocateStrategy,\n    selector: Definition,\n    timeoutOrCallbackOrMessage?: number | NightwatchGenericCallback<boolean> | string,\n    pollIntervalOrAbortOnFailureOrCallbackOrMessage?: number | boolean | NightwatchGenericCallback<boolean> | string,\n    abortOnFailureOrCallbackOrMessage?: boolean | NightwatchGenericCallback<boolean> | string,\n    callbackOrMessage?: NightwatchGenericCallback<boolean> | string,\n    message?: string\n  ): Awaitable<this, true | Error>;\n\n  /**\n   * Returns the computed WAI-ARIA label of an element.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.getAccessibleName('*[name=\"search\"]', function(result) {\n   *       this.assert.equal(typeof result, 'object);\n   *       this.assert.equal(result.value, 'search input');\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getAccessibleName('css selector', '*[name=\"search\"]', function(result) {\n   *       console.log('getAccessibleName result', result.value);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getAccessibleName({\n   *       selector: '*[name=\"search\"]',\n   *       index: 1\n   *     }, function(result) {\n   *       console.log('getAccessibleName result', result.value);\n   *     });\n   *\n   *     browser.getAccessibleName({\n   *       selector: '*[name=\"search\"]',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     }, function(result) {\n   *       console.log('getAccessibleName result', result.value);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function() {\n   *     const result = await browser.getAccessibleName('*[name=\"search\"]');\n   *     console.log('getAccessibleName result', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getAccessibleName.html\n   */\n  getAccessibleName(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n  getAccessibleName(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Returns the computed WAI-ARIA role of an element.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest(browser) {\n   *     browser.getAriaRole('*[name=\"search\"]', function(result) {\n   *       this.assert.equal(typeof result, 'object');\n   *       this.assert.equal(result.value, 'combobox');\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getAriaRole('css selector', '*[name=\"search\"]', function(result) {\n   *       console.log('getAriaRole result', result.value);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getAriaRole({\n   *       selector: '*[name=\"search\"]',\n   *       index: 1\n   *     }, function(result) {\n   *       console.log('getAriaRole result', result.value);\n   *     });\n   *\n   *     browser.getAriaRole({\n   *       selector: '*[name=\"search\"]',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     }, function(result) {\n   *       console.log('getAriaRole result', result.value);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.getAriaRole('*[name=\"search\"]');\n   *     console.log('getAriaRole result', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getAriaRole.html\n   */\n  getAriaRole(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n  getAriaRole(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Determine an element's size in pixels. For W3C Webdriver compatible clients (such as GeckoDriver), this command is equivalent to `getLocation` and both return\n   * the dimensions and coordinates of the given element:\n   * - x: X axis position of the top-left corner of the element, in CSS pixels\n   * - y: Y axis position of the top-left corner of the element, in CSS pixels\n   * - height: Height of the element’s bounding rectangle in CSS pixels;\n   * - width: Width of the web element’s bounding rectangle in CSS pixels.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest() {\n   *     browser.getElementSize('#login', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getElementSize('css selector', '#login', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getElementSize({\n   *       selector: '#login',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     }, function(result) {\n   *       console.log('result', result);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function() {\n   *     const result = await browser.getElementSize('#login');\n   *     console.log('classList', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getElementRect.html\n   */\n  getElementRect(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchSizeAndPosition>\n    ) => void\n  ): Awaitable<this, NightwatchSizeAndPosition>;\n  getElementRect(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchSizeAndPosition>\n    ) => void\n  ): Awaitable<this, NightwatchSizeAndPosition>;\n\n  /**\n   *\n   * Uploads file to an element using absolute file path.\n   *\n   *\n   * @example\n   * // send a file to for upload to a field.\n   * this.demoTest = function (browser) {\n   *   browser.uploadFile('#myFile', '/path/file.pdf');\n   * };\n   *\n   *\n   * @see https://nightwatchjs.org/api/uploadFile.html\n   */\n  uploadFile(\n    selector: Definition,\n    filePath: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  uploadFile(\n    using: LocateStrategy,\n    selector: Definition,\n    filePath: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Sends some text to an element. Can be used to set the value of a form element or\n   *  to send a sequence of key strokes to an element. Any UTF-8 character may be specified.\n   *\n   * <div class=\"alert alert-warning\"><strong>updateValue</strong> is equivalent\n   * with <strong>setValue</strong> and <strong>sendKeys</strong> with the exception\n   * that it clears the value beforehand.</div>\n   *\n   * An object map with available keys and their respective UTF-8 characters,\n   * as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types),\n   * is loaded onto the main Nightwatch instance as `browser.Keys`.\n   *\n   * @example\n   * // send some simple text to an input\n   * this.demoTest = function (browser) {\n   *   browser.updateValue('input[type=text]', 'nightwatch');\n   * };\n   *\n   * // send some text to an input and hit enter.\n   * this.demoTest = function (browser) {\n   *   browser.updateValue('input[type=text]', ['nightwatch', browser.Keys.ENTER]);\n   * };\n   *\n   * @see https://nightwatchjs.org/api/updateValue.html\n   */\n  updateValue(\n    selector: Definition,\n    inputValue: string | string[],\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  updateValue(\n    using: LocateStrategy,\n    selector: Definition,\n    inputValue: string | string[],\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  /**\n   * Drag an element to the given position or destination element.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest(browser) {\n   *     browser.dragAndDrop('#main', {x: 100, y:100}):\n   *\n   *\n   *\n   *  //using webElement as a destination\n   *   demoTestAsync: async function(browser) {\n   *     const destination = await browser.findElement('#upload');\n   *     browser.dragAndDrop('#main', destination.getId());\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/dragAndDrop.html\n   */\n  dragAndDrop(\n    selector: Definition,\n    destination: NightwatchElement | NightwatchPosition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  dragAndDrop(\n    using: LocateStrategy,\n    selector: Definition,\n    destination: NightwatchElement | NightwatchPosition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Returns an element's first child. The child element will be returned as web\n   * element JSON object (with an added .getId() convenience method).\n   *\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test': function(browser) {\n   *     const resultElement = await browser.getFirstElementChild('.features-container');\n   *\n   *     console.log('last child element Id:', resultElement.getId());\n   *   },\n   *\n   * @see https://nightwatchjs.org/api/getFirstElementChild.html\n   */\n  getFirstElementChild(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT>;\n  getFirstElementChild(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT>;\n\n  /**\n   * Returns an element's last child. The child element will be returned\n   * as web element JSON object (with an added .getId() convenience method).\n   *\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test': function(browser) {\n   *     const resultElement = await browser.getLastElementChild('.features-container');\n   *\n   *     console.log('last child element Id:', resultElement.getId());\n   *   },\n   *\n   * @see https://nightwatchjs.org/api/getLastElementChild.html\n   */\n  getLastElementChild(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT>;\n  getLastElementChild(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT>;\n\n  /**\n   * Returns the element immediately following the specified one in their parent's childNodes.\n   * The element will be returned as web element JSON object (with an added .getId() convenience method).\n   *\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test': function(browser) {\n   *     const resultElement = await browser.getNextSibling('.features-container li:first-child');\n   *\n   *     console.log('next sibling element Id:', resultElement.getId());\n   *   },\n   *\n   * @see https://nightwatchjs.org/api/getNextSibling.html\n   */\n  getNextSibling(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT>;\n  getNextSibling(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT>;\n\n  /**\n   *  Returns the element immediately preceding the specified one in its parent's child elements list.\n   * The element will be returned as web element JSON object (with an added `.getId()` convenience method).\n   *\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test': function(browser) {\n   *     const resultElement = await browser.getPreviousSibling('.features-container li:second-child');\n   *\n   *     console.log('previous sibling element Id:', resultElement.getId());\n   *   },\n   *\n   * browser.getPreviousSibling('#web-button', function(result) {\n   *\n   *   console.log(result.value)\n   * }})\n   * await browser.getPreviousSibling('#web-button')\n   * await browser.getPreviousSibling({selector: '#web-button', locateStrategy: 'css selector'})\n   *\n   * // with global element():\n   * const formEl = element('form');\n   * const result = await browser.getPreviousSibling(formEl)\n   *\n   * // with Selenium By() locators\n   * // https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_By.html\n   * const locator = by.tagName('form');\n   * const result = await browser.getPreviousSibling(locator)\n   *\n   * // with browser.findElement()\n   * const formEl = await browser.findElement('form');\n   * const result = await browser.getPreviousSibling(formEl)\n   *\n   * @see https://nightwatchjs.org/api/getPreviousSibling.html\n   */\n  getPreviousSibling(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT>;\n  getPreviousSibling(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT>;\n\n  /**\n   * Returns true or false based on whether the DOM has any child nodes\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test': function(browser) {\n   *     const result = await browser.hasDescendants('.features-container');\n   *\n   *     console.log('true or false:', result);\n   *   },\n   *\n   * @see https://nightwatchjs.org/api/hasDescendants.html\n   */\n  hasDescendants(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n  hasDescendants(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   * Returns the `shadowRoot` read-only property which represents the shadow root hosted by the element.\n   *  This can further be used to retrieve elements part of the shadow root element.\n   *\n   * @example\n   * describe('Shadow Root example test', function() {\n   *   it('retrieve the shadowRoot', async function(browser) {\n   *      await browser\n   *        .navigateTo('https://mdn.github.io/web-components-examples/popup-info-box-web-component/')\n   *        .waitForElementVisible('form');\n   *\n   *      const shadowRootEl = await browser.getShadowRoot('popup-info');\n   *      const infoElement = await shadowRootEl.find('.info');\n   *\n   *      await expect(infoElement.property('innerHTML')).to.include('card validation code');\n   *      const iconElement = await shadowRootEl.find('.icon');\n   *      const firstElement = await browser.getFirstElementChild(iconElement);\n   *\n   *      await expect.element(firstElement).to.be.an('img');\n   *    });\n   * });\n   *\n   * @see https://nightwatchjs.org/api/getShadowRoot.html\n   */\n  getShadowRoot(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<ElementGlobal | null>\n    ) => void\n  ): Awaitable<this, ElementGlobal | null>;\n  getShadowRoot(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<ElementGlobal | null>\n    ) => void\n  ): Awaitable<this, ElementGlobal | null>;\n\n  /**\n   * Search for an elements on the page, starting from the document root. The located element will be returned as web element JSON object (with an added .getId() convenience method).\n   * First argument is the element selector, either specified as a string or as an object (with 'selector' and 'locateStrategy' properties).\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test': function(browser) {\n   *     const resultElement = await browser.findElement('.features-container li:first-child');\n   *\n   *     console.log('Element Id:', resultElement.getId());\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/findElement.html\n   */\n  findElement(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT>;\n  findElement(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT>;\n\n  /**\n   * Search for multiple elements on the page, starting from the document root. The located elements will be returned as web element JSON objects (with an added .getId() convenience method).\n   * First argument is the element selector, either specified as a string or as an object (with 'selector' and 'locateStrategy' properties).\n   *\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test': function(browser) {\n   *     const resultElements = await browser.findElements('.features-container li');\n   *\n   *     resultElements.forEach(item => console.log('Element Id:', item.getId()));\n   *   },\n   *\n   * @see https://nightwatchjs.org/api/findElements.html\n   */\n  findElements(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT[]>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT[]>;\n  findElements(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<JSON_WEB_OBJECT[]>\n    ) => void\n  ): Awaitable<this, JSON_WEB_OBJECT[]>;\n\n  /**\n   * Retrieve the value of a specified DOM property for the given element.\n   * For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n   *\n   * @example\n   * module.exports = {\n   *   demoTest(browser) {\n   *     browser.getElementProperty('#login input[type=text]', 'classList', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.getElementProperty('css selector', '#login input[type=text]', 'classList', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.getElementProperty({\n   *       selector: '#login input[type=text]',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     }, 'classList', function(result) {\n   *       console.log('result', result);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.getElementProperty('#login input[type=text]', 'classList');\n   *     console.log('classList', result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/getElementProperty.html\n   */\n  getElementProperty(\n    selector: Definition,\n    property: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<any>\n    ) => void\n  ): Awaitable<this, any>;\n  getElementProperty(\n    using: LocateStrategy,\n    selector: Definition,\n    property: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<any>\n    ) => void\n  ): Awaitable<this, any>;\n\n  /**\n   *\n   * Determines if an element is enabled, as indicated by the 'disabled' attribute.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest(browser) {\n   *     browser.isEnabled('#main select option.first', function(result) {\n   *       this.assert.equal(typeof result, \"object\");\n   *       this.assert.equal(result.status, 0);\n   *       this.assert.equal(result.value, true);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.isEnabled('css selector', '#main select option.first');\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.isEnabled({\n   *       selector: '#main ul li a',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     });\n   *\n   *     browser.isEnabled({\n   *       selector: '#main select option.first',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.isEnabled('#main select option.first');\n   *     console.log('isVisible result', result);\n   *   }\n   * }\n   * @see https://nightwatchjs.org/api/isEnabled.html\n   */\n  isEnabled(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n  isEnabled(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   *\n   * Determines if an element is selected.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest(browser) {\n   *     browser.isSelected('#main select option.first', function(result) {\n   *       this.assert.equal(typeof result, \"object\");\n   *       this.assert.equal(result.status, 0);\n   *       this.assert.equal(result.value, true);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.isSelected('css selector', '#main select option.first');\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.isSelected({\n   *       selector: '#main ul li a',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     });\n   *\n   *     browser.isSelected({\n   *       selector: '#main select option.first',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.isSelected('#main select option.first');\n   *     console.log('isVisible result', result);\n   *   }\n   * }\n   * @see https://nightwatchjs.org/api/isSelected.html\n   */\n  isSelected(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n  isSelected(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   *\n   * Set the value of a specified DOM attribute for the given element.\n   * For all the available DOM attributes, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n   *\n   * @example\n   * module.exports = {\n   *   demoTest(browser) {\n   *     browser.setAttribute('#login input[type=text]', 'disabled', 'true', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.setAttribute('css selector', '#login input[type=text]', 'disabled', 'true', function(result) {\n   *       console.log('result', result);\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.setAttribute({\n   *       selector: '#login input[type=text]',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     }, 'disabled', 'true', function(result) {\n   *       console.log('result', result);\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     await browser.setAttribute('#login input[type=text]', 'disabled', 'true');\n   *   }\n   * }\n   * @see https://nightwatchjs.org/api/setAttribute.html\n   */\n  setAttribute(\n    selector: Definition,\n    attribute: string,\n    value: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n  setAttribute(\n    using: LocateStrategy,\n    selector: Definition,\n    attribute: string,\n    value: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   *\n   * An alias of \"setValue\" command, but hides the content from the nightwatch logs.\n   *\n   * <div class=\"alert alert-warning\"><strong>setValue/setPassword</strong> do not clear\n   * the existing value of the element. To do so, use the <strong>clearValue()</strong> command.</div>\n   *\n   * An object map with available keys and their respective UTF-8 characters,\n   *  as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types), is loaded onto the main Nightwatch instance as `browser.Keys`.\n   *\n   * @example\n   * // send some simple text to an input\n   * this.demoTest = function (browser) {\n   *   browser.setPassword('input[type=text]', 'nightwatch');\n   * };\n   * //\n   * // send some text to an input and hit enter.\n   * this.demoTest = function (browser) {\n   *   browser.setPassword('input[type=text]', ['nightwatch', browser.Keys.ENTER]);\n   * };\n   *\n   */\n  setPassword(\n    selector: Definition,\n    inputValue: string | string[],\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  setPassword(\n    using: LocateStrategy,\n    selector: Definition,\n    inputValue: string | string[],\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   *\n   * Take a screenshot of the visible region encompassed by this element's bounding rectangle.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest(browser) {\n   *     browser.takeElementScreenshot('#main', function (imageData, err) {\n   *       require('fs').writeFile('out.png', imageData.value, 'base64', function (err) {\n   *         console.log(err);\n   *       });\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.takeElementScreenshot('css selector', '#main', function(imageData, err) {\n   *       require('fs').writeFile('out.png', imageData.value, 'base64', function (err) {\n   *         console.log(err);\n   *       });\n   *     });\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide/writing-tests/finding-interacting-with-dom-elements.html#postdoc-element-properties\n   *     browser.takeElementScreenshot({\n   *       selector: '#main ul li a',\n   *       index: 1\n   *     }, function(imageData, err) {\n   *       require('fs').writeFile('out.png', imageData.value, 'base64', function (err) {\n   *         console.log(err);\n   *       });\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const data = await browser.takeElementScreenshot('#main');\n   *     require('fs').writeFile('out.png', data, 'base64');\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/takeElementScreenshot.html\n   */\n  takeElementScreenshot(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n  takeElementScreenshot(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Will uncheck, click, on a checked checkbox or radio input if not already unchecked.\n   *\n   * @example\n   * module.exports = {\n   *   demoTest(browser) {\n   *     browser.uncheck('input[type=checkbox]:checked)');\n   *\n   *     browser.uncheck('input[type=checkbox]:checked)', function(result) {\n   *       console.log('Check result', result);\n   *     });\n   *\n   *     // with explicit locate strategy\n   *     browser.uncheck('css selector', 'input[type=checkbox]:checked)');\n   *\n   *     // with selector object - see https://nightwatchjs.org/guide#element-properties\n   *     browser.uncheck({\n   *       selector: 'input[type=checkbox]:checked)',\n   *       index: 1,\n   *       suppressNotFoundErrors: true\n   *     });\n   *\n   *     browser.uncheck({\n   *       selector: 'input[type=checkbox]:checked)',\n   *       timeout: 2000 // overwrite the default timeout (in ms) to check if the element is present\n   *     });\n   *   },\n   *\n   *   demoTestAsync: async function(browser) {\n   *     const result = await browser.uncheck('input[type=checkbox]:checked)');\n   *     console.log('Check result', result);\n   *   }\n   * }\n   * \n   * Will uncheck, click, on a checked checkbox or radio input if not already unchecked.\n   *\n   * @see https://nightwatchjs.org/api/uncheck.html\n   */\n  uncheck(\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  uncheck(\n    using: LocateStrategy,\n    selector: Definition,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n}\n\nexport interface AppiumCommands<ReturnType = unknown> {\n  /**\n   * Get the current device orientation.\n   *\n   * @example\n   * module.exports = {\n   *   'get current device orientation': function (app) {\n   *     app\n   *       .appium.getOrientation(function (result) {\n   *         console.log('current device orientation is:', result.value);\n   *       });\n   *   },\n   *\n   *   'get current device orientation with ES6 async/await': async function (app) {\n   *     const orientation = await app.appium.getOrientation();\n   *     console.log('current device orientation is:', orientation);\n   *   }\n   * };\n   */\n  getOrientation(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<'LANDSCAPE' | 'PORTRAIT'>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, 'LANDSCAPE' | 'PORTRAIT'>;\n\n  /**\n   * Set the current device orientation.\n   *\n   * @example\n   * module.exports = {\n   *   'set orientation to LANDSCAPE': function (app) {\n   *     app\n   *       .appium.setOrientation('LANDSCAPE');\n   *   }\n   * };\n   */\n  setOrientation(\n    orientation: 'LANDSCAPE' | 'PORTRAIT',\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<'LANDSCAPE' | 'PORTRAIT'>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, 'LANDSCAPE' | 'PORTRAIT'>;\n\n  /**\n   * Get a list of the available contexts. Used when testing hybrid mobile apps using Appium.\n   *\n   * More info here: https://appium.io/docs/en/commands/context/get-contexts/\n   *\n   * @example\n   * module.exports = {\n   *   'get available contexts': function (app) {\n   *     app\n   *       .appium.getContexts(function (result) {\n   *         console.log('the available contexts are:', result.value);\n   *       });\n   *   },\n   *\n   *   'get available contexts with ES6 async/await': async function (app) {\n   *     const contexts = await app.appium.getContexts();\n   *     console.log('the available contexts are:', contexts);\n   *   }\n   * };\n   */\n  getContexts(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string[]>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, string[]>;\n\n  /**\n   * Get the current context in which Appium is running. Used when testing hybrid mobile apps using Appium.\n   *\n   * More info here: https://appium.io/docs/en/commands/context/get-context/\n   *\n   * @example\n   * module.exports = {\n   *   'get current context': function (app) {\n   *     app\n   *       .appium.getContext(function (result) {\n   *         console.log('the current context is:', result.value);\n   *       });\n   *   },\n   *\n   *   'get current context with ES6 async/await': async function (app) {\n   *     const context = await app.appium.getContext();\n   *     console.log('the current context is:', context);\n   *   }\n   * };\n   */\n  getContext(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string | null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, string | null>;\n\n  /**\n   * Set the context to be automated. Used when testing hybrid mobile apps using Appium.\n   *\n   * More info here: https://appium.io/docs/en/commands/context/set-context/\n   *\n   * @example\n   * module.exports = {\n   *   'switch to webview context': async function (app) {\n   *     app\n   *       .waitUntil(async function() {\n   *         // wait for webview context to be available\n   *         // initially, this.getContexts() only returns ['NATIVE_APP']\n   *         const contexts = await this.appium.getContexts();\n   *\n   *         return contexts.length > 1;\n   *       })\n   *       .perform(async function() {\n   *         // switch to webview context\n   *         const contexts = await this.appium.getContexts();  // contexts: ['NATIVE_APP', 'WEBVIEW_<id>']\n   *         await this.appium.setContext(contexts[1]);\n   *       });\n   *   },\n   *\n   *   'switch to native context': function (app) {\n   *     app.appium.setContext('NATIVE_APP');\n   *   }\n   * };\n   */\n  setContext(\n    context: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Reset the current session (run delete and create session).\n   *\n   * More info here: https://appium.io/docs/en/2.3/commands/base-driver/#reset\n   *\n   * @example\n   * module.exports = {\n   *   'start an android activity': function (app) {\n   *     app\n   *       .appium.resetApp();\n   *   },\n   *\n   *   'reset the app activity and wait for onboarding activity to start': function (app) {\n   *     app\n   *       .appium.resetApp();\n   *   }\n   * };\n   */\n  resetApp(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n  /**\n   * Start an Android activity by providing package name, activity name and other optional parameters.\n   *\n   * More info here: https://appium.io/docs/en/commands/device/activity/start-activity/\n   *\n   * @example\n   * module.exports = {\n   *   'start an android activity': function (app) {\n   *     app\n   *       .appium.startActivity({\n   *         appPackage: 'com.android.chrome',\n   *         appActivity: 'com.google.android.apps.chrome.Main'\n   *       });\n   *   },\n   *\n   *   'start the main Android activity and wait for onboarding activity to start': function (app) {\n   *     app\n   *       .appium.startActivity({\n   *         appPackage: 'org.wikipedia',\n   *         appActivity: 'org.wikipedia.main.MainActivity',\n   *         appWaitActivity: 'org.wikipedia.onboarding.InitialOnboardingActivity'\n   *       });\n   *   }\n   * };\n   */\n  startActivity(\n    opts: {\n      appPackage: string;\n      appActivity: string;\n      appWaitPackage?: string;\n      appWaitActivity?: string;\n      intentAction?: string;\n      intentCategory?: string;\n      intentFlags?: string;\n      optionalIntentArguments?: string;\n      dontStopAppOnReset?: boolean;\n    },\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Get the name of the current Android activity.\n   *\n   * @example\n   * module.exports = {\n   *   'get current activity name': function (app) {\n   *     app\n   *       .appium.getCurrentActivity(function (result) {\n   *         console.log('current android activity is:', result.value);\n   *       });\n   *   },\n   *\n   *   'get current activity name with ES6 async/await': async function (app) {\n   *     const activity = await app.appium.getCurrentActivity();\n   *     console.log('current android activity is:', activity);\n   *   }\n   * };\n   */\n  getCurrentActivity(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, string>;\n\n  /**\n   * Get the name of the current Android package.\n   *\n   * @example\n   * module.exports = {\n   *   'get current package name': function (app) {\n   *     app\n   *       .appium.getCurrentPackage(function (result) {\n   *         console.log('current android package is:', result.value);\n   *       });\n   *   },\n   *\n   *   'get current package name with ES6 async/await': async function (app) {\n   *     const packageName = await app.appium.getCurrentPackage();\n   *     console.log('current android package is:', packageName);\n   *   }\n   * };\n   */\n  getCurrentPackage(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, string>;\n\n  /**\n   * Get the current geolocation of the mobile device.\n   *\n   * @example\n   * module.exports = {\n   *   'get device geolocation': function (app) {\n   *     app\n   *       .appium.getGeolocation(function (result) {\n   *         console.log('current device geolocation is:', result.value);\n   *       });\n   *   },\n   *\n   *   'get device geolocation with ES6 async/await': async function (app) {\n   *     const location = await app.appium.getGeolocation();\n   *     console.log('current device geolocation is:', location);\n   *   }\n   * };\n   */\n  getGeolocation(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<AppiumGeolocation>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, AppiumGeolocation>;\n\n  /**\n   * Set the current geolocation of the mobile device.\n   *\n   * @example\n   * module.exports = {\n   *   'set geolocation to Tokyo, Japan': function (app) {\n   *     app\n   *       .appium.setGeolocation({latitude: 35.689487, longitude: 139.691706, altitude: 5});\n   *   },\n   *\n   *   'set geolocation to Tokyo, Japan with ES6 async/await': async function (app) {\n   *     await app.appium.setGeolocation({latitude: 35.689487, longitude: 139.691706});\n   *   }\n   * };\n   */\n  setGeolocation(\n    coordinates: AppiumGeolocation,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<AppiumGeolocation>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, AppiumGeolocation>;\n\n  /**\n   * Press a particular key on an Android Device.\n   *\n   * See [official Android Developers docs](https://developer.android.com/reference/android/view/KeyEvent.html) for reference of available Android key code values.\n   *\n   * @example\n   * module.exports = {\n   *   'press e with caps lock on (keycode 33 and metastate 1048576)': function (app) {\n   *     app\n   *       .appium.pressKeyCode(33, 1048576);\n   *   },\n   *\n   *   'press g (keycode 35) with ES6 async/await': async function (app) {\n   *     await app.appium.pressKeyCode(35);\n   *   }\n   * };\n   */\n  pressKeyCode(\n    keycode: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n  pressKeyCode(\n    keycode: number,\n    metastate?: number,\n    flags?: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Press and hold a particular key on an Android Device.\n   *\n   * See [official Android Developers docs](https://developer.android.com/reference/android/view/KeyEvent.html) for reference of available Android key code values.\n   *\n   * @example\n   * module.exports = {\n   *   'long press e with caps lock on (keycode 33 and metastate 1048576)': function (app) {\n   *     app\n   *       .appium.longPressKeyCode(33, 1048576);\n   *   },\n   *\n   *   'long press g (keycode 35) with ES6 async/await': async function (app) {\n   *     await app.appium.longPressKeyCode(35);\n   *   }\n   * };\n   */\n  longPressKeyCode(\n    keycode: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n  longPressKeyCode(\n    keycode: number,\n    metastate?: number,\n    flags?: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Hide soft keyboard.\n   *\n   * @example\n   * module.exports = {\n   *   'hide device soft keyboard': function (app) {\n   *     app\n   *       .appium.hideKeyboard();\n   *   },\n   *\n   *   'hide device soft keyboard with ES6 async/await': async function (app) {\n   *     await app.appium.hideKeyboard();\n   *   }\n   * };\n   */\n  hideKeyboard(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, boolean>;\n\n  /**\n   * Whether or not the soft keyboard is shown.\n   *\n   * @example\n   * module.exports = {\n   *   'whether keyboard is shown': function (app) {\n   *     app\n   *       .appium.isKeyboardShown(function (result) {\n   *         console.log('result value of whether keyboard is shown:', result.value);\n   *       });\n   *   },\n   *\n   *   'whether keyboard is shown with ES6 async/await': async function (app) {\n   *     const result = await app.appium.isKeyboardShown();\n   *     console.log('result value of whether keyboard is shown:', result);\n   *   }\n   * };\n   */\n  isKeyboardShown(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, boolean>;\n}\n\nexport interface Cookie {\n  name: string;\n  value: string;\n  path?: string;\n  domain?: string;\n  secure?: boolean;\n  httpOnly?: boolean;\n  expiry?: number;\n  sameSite?: 'Lax' | 'Strict' | 'None';\n}\n\nexport interface CookiesNsCommands<ReturnType = unknown> {\n  /**\n   * Retrieve a single cookie visible to the current page.\n   *\n   * The cookie is returned as a cookie JSON object, with properties as defined [here](https://www.w3.org/TR/webdriver/#dfn-table-for-cookie-conversion).\n   *\n   * @example\n   * module.exports = {\n   *   'get a cookie': function (browser) {\n   *     browser\n   *       .cookies.get('test_cookie', function (result) {\n   *         const cookie = result.value;\n   *         this.assert.equal(cookie.name, 'test_cookie');\n   *         this.assert.equal(cookie.value, '123456');\n   *       });\n   *   },\n   *\n   *   'get a cookie with ES6 async/await': async function (browser) {\n   *     const cookie = await browser.cookies.get('test_cookie');\n   *     browser.assert.equal(cookie.name, 'test_cookie');\n   *     browser.assert.equal(cookie.value, '123456');\n   *   }\n   * };\n   */\n  get(\n    name: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<Cookie | null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, Cookie | null>;\n\n  /**\n   * Retrieve all cookies visible to the current page.\n   *\n   * The cookies are returned as an array of cookie JSON object, with properties as defined [here](https://www.w3.org/TR/webdriver/#dfn-table-for-cookie-conversion).\n   *\n   * @example\n   * module.exports = {\n   *   'get all cookies': function (browser) {\n   *     browser\n   *       .cookies.getAll(function (result) {\n   *         this.assert.equal(result.value.length, 1);\n   *         this.assert.equal(result.value[0].name, 'test_cookie');\n   *       });\n   *   },\n   *\n   *   'get all cookies with ES6 async/await': async function (browser) {\n   *     const cookies = await browser.cookies.getAll();\n   *     browser.assert.equal(cookies.length, 1);\n   *     browser.assert.equal(cookies[0].name, 'test_cookie');\n   *   }\n   * };\n   */\n  getAll(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<Cookie[]>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, Cookie[]>;\n\n  /**\n   * Set a cookie, specified as a cookie JSON object, with properties as defined [here](https://www.w3.org/TR/webdriver/#dfn-table-for-cookie-conversion).\n   *\n   * @example\n   * module.exports = {\n   *   'set a cookie': function (browser) {\n   *     browser\n   *       .cookies.set({\n   *         name: \"test_cookie\",\n   *         value: \"test_value\",\n   *         path: \"/\", // (Optional)\n   *         domain: \"example.org\", // (Optional)\n   *         secure: false, // (Optional)\n   *         httpOnly: false, // (Optional)\n   *         expiry: 1395002765 // (Optional) time in seconds since midnight, January 1, 1970 UTC\n   *       });\n   *   },\n   *\n   *   'set a cookie with ES6 async/await': async function (browser) {\n   *     await browser.cookies.set({\n   *       name: 'test_cookie',\n   *       value: 'test_value',\n   *       domain: 'example.org', // (Optional)\n   *       sameSite: 'Lax' // (Optional)\n   *     });\n   *   }\n   * };\n   */\n  set(\n    cookie: Cookie,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Delete the cookie with the given name. This command is a no-op if there is no such cookie visible to the current page.\n   *\n   * @example\n   * module.exports = {\n   *   'delete a cookie': function (browser) {\n   *     browser\n   *       .cookies.delete('test_cookie', function () {\n   *         console.log('cookie deleted successfully');\n   *       });\n   *   },\n   *\n   *   'delete a cookie with ES6 async/await': async function (browser) {\n   *     await browser.cookies.delete('test_cookie');\n   *   }\n   * };\n   */\n  delete(\n    cookieName: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Delete all cookies visible to the current page.\n   *\n   * @example\n   * module.exports = {\n   *   'delete all cookies': function (browser) {\n   *     browser\n   *       .cookies.deleteAll(function() {\n   *         console.log('all cookies deleted successfully');\n   *       });\n   *   },\n   *\n   *   'delete all cookies with ES6 async/await': async function (browser) {\n   *     await browser.cookies.deleteAll();\n   *   }\n   * };\n   */\n  deleteAll(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n}\n\ntype FirefoxContext = 'content' | 'chrome';\nexport interface FirefoxNsCommands<ReturnType = unknown> {\n  getContext(): Awaitable<IfUnknown<ReturnType, this>, FirefoxContext>;\n  setContext(ctx: FirefoxContext | PromiseLike<FirefoxContext>): Awaitable<IfUnknown<ReturnType, this>, null>;\n  installAddon(path: string, temporary?: boolean): Awaitable<IfUnknown<ReturnType, this>, string>;\n  uninstallAddon(addonId: string | PromiseLike<string>): Awaitable<IfUnknown<ReturnType, this>, null>;\n}\n\ntype NetworkConditionsSpec = {\n  offline: boolean,\n  latency: number,\n  download_throughput: number,\n  upload_throughput: number\n};\n\nexport interface ChromeNsCommands<ReturnType = unknown> {\n  /**\n   * Launch Chrome App with given ID.\n   * @param id ID of the App to launch.\n   */\n  launchApp(\n    id: string\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Get Chromium network emulation settings.\n   *\n   * Network conditions must be set before it can be retrieved.\n   */\n  getNetworkConditions(): Awaitable<IfUnknown<ReturnType, this>, NetworkConditionsSpec>;\n\n  /**\n   * Set Chromium network emulation settings.\n   *\n   * @example\n   * describe('set network conditions', function() {\n   *  it('sets the network conditions', function() {\n   *    browser\n   *     .chrome.setNetworkConditions({\n   *       offline: false,\n   *       latency: 5, // Additional latency (ms).\n   *       download_throughput: 500 * 1024, // Maximal aggregated download throughput.\n   *       upload_throughput: 500 * 1024 // Maximal aggregated upload throughput.\n   *    });\n   *  });\n   * });\n   *\n   * @param spec Defines the network conditions to set\n   */\n  setNetworkConditions(\n    spec: NetworkConditionsSpec\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Delete Chromium network emulation settings.\n   */\n  deleteNetworkConditions(): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Sends an arbitrary devtools command to the browser.\n   *\n   * @param cmd The name of the command to send.\n   * @param params The command parameters.\n   * @see <https://chromedevtools.github.io/devtools-protocol/>\n   */\n  sendDevToolsCommand(\n    cmd: string,\n    params?: { [key: string]: any }\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Sends an arbitrary devtools command to the browser and get the result.\n   *\n   * @param cmd The name of the command to send.\n   * @param params The command parameters.\n   * @see <https://chromedevtools.github.io/devtools-protocol/>\n   */\n  sendAndGetDevToolsCommand(\n    cmd: string,\n    params?: { [key: string]: any }\n  ): Awaitable<IfUnknown<ReturnType, this>, unknown>;\n\n  /**\n   * Set a permission state to the given value.\n   *\n   * @param name A name of the permission to update.\n   * @param state State to set permission to.\n   * @see <https://w3c.github.io/permissions/#permission-registry> for valid names\n   */\n  setPermission(\n    name: string,\n    state: 'granted' | 'denied' | 'prompt'\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Sends a DevTools command to change the browser's download directory.\n   *\n   * @param path The desired download directory.\n   * @see chrome.sendDevToolsCommand\n   */\n  setDownloadPath(\n    path: string\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Returns the list of cast sinks (Cast devices) available to the Chrome media router.\n   *\n   * @return An array of Strings containing the friendly device names of available cast sink targets.\n   */\n  getCastSinks(): Awaitable<IfUnknown<ReturnType, this>, string[]>;\n\n  /**\n   * Selects a cast sink (Cast device) as the recipient of media router intents (connect or play).\n   *\n   * @param deviceName name of the target device.\n   */\n  setCastSinkToUse(\n    deviceName: string\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Initiates tab mirroring for the current browser tab on the specified device.\n   *\n   * @param deviceName name of the target device.\n   */\n  startCastTabMirroring(\n    deviceName: string\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Returns an error message when there is any issue in a Cast session.\n   */\n  getCastIssueMessage(): Awaitable<IfUnknown<ReturnType, this>, string>;\n\n  /**\n   * Stops casting from media router to the specified device, if connected.\n   *\n   * @param deviceName name of the target device.\n   */\n  stopCasting(\n    deviceName: string\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n}\n\nexport interface NetworkNsCommands<ReturnType = unknown> {\n  /**\n   * Capture outgoing network calls from the browser.\n   *\n   * @example\n   *  describe('capture network requests', function() {\n   *    it('captures and logs network requests as they occur', function(this: ExtendDescribeThis<{requestCount: number}>) {\n   *      this.requestCount = 1;\n   *      browser\n   *        .network.captureRequests((requestParams) => {\n   *          console.log('Request Number:', this.requestCount!++);\n   *          console.log('Request URL:', requestParams.request.url);\n   *          console.log('Request method:', requestParams.request.method);\n   *          console.log('Request headers:', requestParams.request.headers);\n   *        })\n   *        .navigateTo('https://www.google.com');\n   *    });\n   *  });\n   *\n   * @see https://nightwatchjs.org/guide/network-requests/capture-network-calls.html\n   */\n  captureRequests(\n    onRequestCallback: (\n      requestParams: Protocol.Network.RequestWillBeSentEvent\n    ) => void,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Intercept the request made on a particular URL and mock the response.\n   *\n   * @example\n   *  describe('mock network response', function() {\n   *    it('intercepts the request made to Google search and mocks its response', function() {\n   *      browser\n   *        .network.mockResponse('https://www.google.com/', {\n   *          status: 200,\n   *          headers: {\n   *            'Content-Type': 'UTF-8'\n   *          },\n   *          body: 'Hello there!'\n   *        })\n   *        .navigateTo('https://www.google.com/')\n   *        .pause(2000);\n   *    });\n   *  });\n   *\n   * @see https://nightwatchjs.org/guide/network-requests/mock-network-response.html\n   */\n  mockResponse(\n    urlToIntercept: string,\n    response?: {\n      status?: Protocol.Fetch.FulfillRequestRequest['responseCode'];\n      headers?: { [name: string]: string };\n      body?: Protocol.Fetch.FulfillRequestRequest['body'];\n    },\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Command to set Chrome network emulation settings.\n   *\n   * @example\n   * describe('set network conditions', function() {\n   *  it('sets the network conditions',function() {\n   *    browser\n   *     .network.setConditions({\n   *      offline: false,\n   *      latency: 3000,\n   *      download_throughput: 500 * 1024,\n   *      upload_throughput: 500 * 1024\n   *    });\n   *  });\n   * });\n   *\n   * @see https://nightwatchjs.org/api/setNetworkConditions.html\n   */\n  setConditions(\n    spec: NetworkConditionsSpec,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n}\n\nexport interface AlertsNsCommands<ReturnType = unknown> {\n  /**\n   * Accepts the currently displayed alert dialog. Usually, this is equivalent to clicking on the 'OK' button in the dialog.\n   *\n   * @example\n   * module.exports = {\n   *   'accept open alert': function (browser) {\n   *     browser\n   *       .alerts.accept(function () {\n   *         console.log('alert accepted successfully');\n   *       });\n   *   },\n   *\n   *   'accept open alert with ES6 async/await': async function (browser) {\n   *     await browser.alerts.accept();\n   *   }\n   * };\n   */\n  accept(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Dismisses the currently displayed alert dialog.\n   *\n   * For confirm() and prompt() dialogs, this is equivalent to clicking the 'Cancel' button.\n   * For alert() dialogs, this is equivalent to clicking the 'OK' button.\n   *\n   * @example\n   * module.exports = {\n   *   'dismiss open alert': function (browser) {\n   *     browser\n   *       .alerts.dismiss(function () {\n   *         console.log('alert dismissed successfully');\n   *       });\n   *   },\n   *\n   *   'dismiss open alert with ES6 async/await': async function (browser) {\n   *     await browser.alerts.dismiss();\n   *   }\n   * };\n   */\n  dismiss(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Get the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog.\n   *\n   * @example\n   * module.exports = {\n   *   'get open alert text': function (browser) {\n   *     browser\n   *       .alerts.getText(function (result) {\n   *         console.log('text on open alert:', result.value);\n   *       });\n   *   },\n   *\n   *   'get open alert text with ES6 async/await': async function (browser) {\n   *     const alertText = await browser.alerts.getText();\n   *     console.log('text on open alert:', alertText);\n   *   }\n   * };\n   */\n  getText(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, string>;\n\n  /**\n   * Send keystrokes to a JavaScript prompt() dialog.\n   *\n   * @example\n   * module.exports = {\n   *   'set text on JS prompt': function (browser) {\n   *     browser\n   *       .alerts.setText('some text', function () {\n   *         console.log('text sent to JS prompt successfully');\n   *       });\n   *   },\n   *\n   *   'set text on JS prompt with ES6 async/await': async function (browser) {\n   *     await browser.alerts.setText('some text');\n   *   }\n   * };\n   */\n  setText(\n    value: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n}\n\nexport interface DocumentNsCommands<ReturnType = unknown> {\n  /**\n   * Utility command to load an external script into the page specified by url.\n   *\n   * @example\n   * module.exports = {\n   *   'inject external script': function (browser) {\n   *      browser.document.injectScript('<script-url>', function () {\n   *        console.log('script injected successfully');\n   *      });\n   *   },\n   *\n   *   'inject external script using ES6 async/await': async function (browser) {\n   *      await browser.document.injectScript('<script-url>', 'injected-script');\n   *   }\n   * };\n   */\n  injectScript(\n    scriptUrl: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<WebElement>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, WebElement>;\n  injectScript(\n    scriptUrl: string,\n    id: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<WebElement>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, WebElement>;\n\n  /**\n   * Get the string serialized source of the current page.\n   *\n   * @example\n   * module.exports = {\n   *   'get page source': function (browser) {\n   *      browser.document.source(function (result) {\n   *        console.log('current page source:', result.value);\n   *      });\n   *   },\n   *\n   *   'get page source using ES6 async/await': async function (browser) {\n   *      const pageSource = await browser.document.source();\n   *      console.log('current page source:', pageSource);\n   *   }\n   * };\n   *\n   * @alias document.pageSource\n   */\n  source(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, string>;\n\n  /**\n   * Get the string serialized source of the current page.\n   *\n   * @example\n   * module.exports = {\n   *   'get page source': function (browser) {\n   *      browser.document.pageSource(function (result) {\n   *        console.log('current page source:', result.value);\n   *      });\n   *   },\n   *\n   *   'get page source using ES6 async/await': async function (browser) {\n   *      const pageSource = await browser.document.pageSource();\n   *      console.log('current page source:', pageSource);\n   *   }\n   * };\n   *\n   * @alias document.source\n   */\n  pageSource(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, string>;\n}\n\nexport interface LogsNsCommands<ReturnType = unknown> {\n  /**\n   * Gets a log from Selenium.\n   *\n   * @example\n   * describe('get log from Selenium', function() {\n   *   it('get browser log (default)', function(browser) {\n   *     browser.logs.getSessionLog(function(result) {\n   *       if (result.status === 0) {\n   *         const logEntriesArray = result.value;\n   *         console.log('Log length: ' + logEntriesArray.length);\n   *         logEntriesArray.forEach(function(log) {\n   *           console.log('[' + log.level + '] ' + log.timestamp + ' : ' + log.message);\n   *         });\n   *       }\n   *     });\n   *   });\n   *\n   *   it('get driver log with ES6 async/await', async function(browser) {\n   *     const driverLogAvailable = await browser.logs.isAvailable('driver');\n   *     if (driverLogAvailable) {\n   *       const logEntriesArray = await browser.logs.getSessionLog('driver');\n   *       logEntriesArray.forEach(function(log) {\n   *         console.log('[' + log.level + '] ' + log.timestamp + ' : ' + log.message);\n   *       });\n   *     }\n   *   });\n   * });\n   *\n   * @see https://nightwatchjs.org/api/logs/getSessionLog.html\n   */\n  getSessionLog(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<NightwatchLogEntry[]>) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, NightwatchLogEntry[]>;\n  getSessionLog(\n    typeString: NightwatchLogTypes,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<NightwatchLogEntry[]>) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, NightwatchLogEntry[]>;\n\n  /**\n   * Gets the available log types. More info about log types in WebDriver can be found here: https://github.com/SeleniumHQ/selenium/wiki/Logging\n   *\n   * @example\n   * describe('get available log types', function() {\n   *   it('get log types', function(browser) {\n   *     browser.logs.getSessionLogTypes(function(result) {\n   *       if (result.status === 0) {\n   *         const logTypes = result.value;\n   *         console.log('Log types available:', logTypes);\n   *       }\n   *     });\n   *   });\n   *\n   *   it('get log types with ES6 async/await', async function(browser) {\n   *     const logTypes = await browser.logs.getSessionLogTypes();\n   *     console.log('Log types available:', logTypes);\n   *   });\n   * });\n   *\n   * @see https://nightwatchjs.org/api/logs/getSessionLogTypes.html\n   */\n  getSessionLogTypes(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchLogTypes[]>\n    ) => void\n  ): Awaitable<\n    IfUnknown<ReturnType, this>,\n    NightwatchLogTypes[]\n  >;\n\n  /**\n   * Utility command to test if the log type is available.\n   *\n   * @example\n   * describe('test if the log type is available', function() {\n   *   it('test browser log type', function(browser) {\n   *     browser.logs.isSessionLogAvailable('browser', function(result) {\n   *       if (result.status === 0) {\n   *         const isAvailable = result.value;\n   *         if (isAvailable) {\n   *           // do something more in here\n   *         }\n   *       }\n   *     });\n   *   });\n   *\n   *   it('test driver log type with ES6 async/await', async function(browser) {\n   *     const isAvailable = await browser.logs.isSessionLogAvailable('driver');\n   *     if (isAvailable) {\n   *       // do something more in here\n   *     }\n   *   });\n   * });\n   *\n   * @see https://nightwatchjs.org/api/logs/isSessionLogAvailable.html\n   */\n  isSessionLogAvailable(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<boolean>) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, boolean>;\n  isSessionLogAvailable(\n    typeString: NightwatchLogTypes,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<boolean>) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, boolean>;\n\n  /**\n   * Listen to the `console` events (ex. `console.log` event) and\n   * register callback to process the same.\n   *\n   * @example\n   *  describe('capture console events', function() {\n   *    it('captures and logs console.log event', function() {\n   *      browser\n   *        .captureBrowserConsoleLogs((event) => {\n   *          console.log(event.type, event.timestamp, event.args[0].value);\n   *        })\n   *        .navigateTo('https://www.google.com')\n   *        .executeScript(function() {\n   *          console.log('here');\n   *        }, []);\n   *    });\n   *  });\n   *\n   * @see https://nightwatchjs.org/guide/running-tests/capture-console-messages.html\n   */\n  captureBrowserConsoleLogs(\n    onEventCallback: (\n      event: Pick<\n        Protocol.Runtime.ConsoleAPICalledEvent,\n        'type' | 'timestamp' | 'args'\n      >\n    ) => void,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Catch the JavaScript exceptions thrown in the browser.\n   *\n   * @example\n   *  describe('catch browser exceptions', function() {\n   *    it('captures the js exceptions thrown in the browser', async function() {\n   *      await browser.captureBrowserExceptions((event) => {\n   *        console.log('>>> Exception:', event);\n   *      });\n   *\n   *      await browser.navigateTo('https://duckduckgo.com/');\n   *\n   *      const searchBoxElement = await browser.findElement('input[name=q]');\n   *      await browser.executeScript(function(_searchBoxElement) {\n   *        _searchBoxElement.setAttribute('onclick', 'throw new Error(\"Hello world!\")');\n   *      }, [searchBoxElement]);\n   *\n   *      await browser.elementIdClick(searchBoxElement.getId());\n   *    });\n   *  });\n   *\n   * @see https://nightwatchjs.org/guide/running-tests/catch-js-exceptions.html\n   */\n  captureBrowserExceptions(\n    onExceptionCallback: (event: Protocol.Runtime.ExceptionThrownEvent) => void,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n}\nexport interface WindowNsCommands<ReturnType = unknown> {\n  /**\n   * Close the current window or tab. This can be useful when you're working with multiple windows/tabs open (e.g. an OAuth login).\n   *\n   * After closing a window or tab, you must switch back to a valid window handle (using `.window.switchTo()` command) in order to continue execution.\n   *\n   * @example\n   * module.exports = {\n   *  'close current window/tab': function (browser) {\n   *     browser.window.close(function (result) {\n   *       console.log('current window/tab closed successfully');\n   *     });\n   *   },\n   *\n   *   'close current window/tab with ES6 async/await': async function (browser) {\n   *     await browser.window.close();\n   *   }\n   * };\n   */\n  close(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Opens a new tab (default) or a separate new window, and changes focus to the newly opened tab/window.\n   *\n   * This command is only available for W3C Webdriver compatible browsers.\n   *\n   * @example\n   * module.exports = {\n   *  'open a new tab/window': function (browser) {\n   *     // open a new tab (default)\n   *     browser.window.open(function () {\n   *       console.log('new tab opened successfully');\n   *     });\n   *\n   *     // open a new window\n   *     browser.window.open('window', function () {\n   *       console.log('new window opened successfully');\n   *     });\n   *   },\n   *\n   *   'open a new tab/window ES6 async demo Test': async function (browser) {\n   *     // open a new tab (default)\n   *     await browser.window.open();\n   *\n   *     // open a new window\n   *     await browser.window.open('window');\n   *   }\n   * };\n   *\n   * @alias window.openNew\n   */\n  open(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n  open(\n    type: \"window\" | \"tab\",\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Opens a new tab (default) or a separate new window, and changes focus to the newly opened tab/window.\n   *\n   * This command is only available for W3C Webdriver compatible browsers.\n   *\n   * @example\n   * module.exports = {\n   *  'open a new tab/window': function (browser) {\n   *     // open a new tab (default)\n   *     browser.window.openNew(function () {\n   *       console.log('new tab opened successfully');\n   *     });\n   *\n   *     // open a new window\n   *     browser.window.openNew('window', function () {\n   *       console.log('new window opened successfully');\n   *     });\n   *   },\n   *\n   *   'open a new tab/window ES6 async demo Test': async function (browser) {\n   *     // open a new tab (default)\n   *     await browser.window.openNew();\n   *\n   *     // open a new window\n   *     await browser.window.openNew('window');\n   *   }\n   * };\n   *\n   * @alias window.open\n   */\n  openNew(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n  openNew(\n    type: \"window\" | \"tab\",\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Retrieve the current window handle.\n   *\n   * WebDriver does not make the distinction between windows and tabs. So, if your site opens a new tab or window, you can work with it using a window handle.\n   *\n   * @example\n   * module.exports = {\n   *  'get current window handle': function (browser) {\n   *     browser.window.getHandle(function (result) {\n   *       console.log('current window handle is:', result.value);\n   *     });\n   *   },\n   *\n   *   'get current window handle with ES6 async/await': async function (browser) {\n   *     const windowHandle = await browser.window.getHandle();\n   *     console.log('current window handle is:', windowHandle);\n   *   }\n   * };\n   */\n  getHandle(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, string>;\n\n  /**\n   * Retrieve the list of all window handles available to the session.\n   *\n   * @example\n   * module.exports = {\n   *  'get all window handles': function (browser) {\n   *     browser.window.getAllHandles(function (result) {\n   *       console.log('available window handles are:', result.value);\n   *     });\n   *   },\n   *\n   *   'get all window handles with ES6 async/await': async function (browser) {\n   *     const windowHandles = await browser.window.getAllHandles();\n   *     console.log('available window handles are:', windowHandles);\n   *   }\n   * };\n   */\n  getAllHandles(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string[]>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, string[]>;\n\n  /**\n   * Change focus to another window.\n   *\n   * The window to change focus to must be specified by its server assigned window handle. To find out the window handle, use `window.getAllHandles()` command.\n   *\n   * @example\n   * module.exports = {\n   *  'switch to another window': function (browser) {\n   *     browser\n   *       .navigateTo('https://nightwatchjs.org/__e2e/window/')\n   *       .click('#openWindowBttn')\n   *       .waitUntil(function () {\n   *         // wait until window handle for the new window is available\n   *         return new Promise((resolve) => {\n   *           browser.window.getAllHandles(function (result) {\n   *             resolve(result.value.length === 2);\n   *           });\n   *         });\n   *       })\n   *       .perform(async function () {\n   *         const originalWindow = await browser.window.getHandle();\n   *         const allWindows = await browser.window.getAllHandles();\n   *\n   *         // loop through to find the new window handle\n   *         for (const windowHandle of allWindows) {\n   *           if (windowHandle !== originalWindow) {\n   *             await browser.window.switchTo(windowHandle);\n   *             break;\n   *           }\n   *         }\n   *\n   *         const currentWindow = await browser.window.getHandle();\n   *         browser.assert.notEqual(currentWindow, originalWindow);\n   *       });\n   *   },\n   *\n   *   'switch to another window with ES6 async/await': async function (browser) {\n   *     await browser.navigateTo('https://nightwatchjs.org/__e2e/window/');\n   *     await browser.click('#openWindowBttn');\n   *\n   *     // wait until window handle for the new window is available\n   *     await browser.waitUntil(async function () {\n   *       const windowHandles = await browser.window.getAllHandles();\n   *\n   *       return windowHandles.length === 2;\n   *     });\n   *\n   *     const originalWindow = await browser.window.getHandle();\n   *     const allWindows = await browser.window.getAllHandles();\n   *\n   *     // loop through available windows to find the new window handle\n   *     for (const windowHandle of allWindows) {\n   *       if (windowHandle !== originalWindow) {\n   *         await browser.window.switchTo(windowHandle);\n   *         break;\n   *       }\n   *     }\n   *\n   *     const currentWindow = await browser.window.getHandle();\n   *     await browser.assert.notEqual(currentWindow, originalWindow);\n   *   }\n   * };\n   *\n   * @alias window.switch\n   */\n  switchTo(\n    windowHandle: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n  switch(\n    windowHandle: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Increases the window to the maximum available size without going full-screen.\n   *\n   * @example\n   * module.exports = {\n   *  'maximize current window': function (browser) {\n   *     browser.window.maximize(function () {\n   *       console.log('window maximized successfully');\n   *     });\n   *   },\n   *\n   *   'maximize current window using ES6 async/await': async function (browser) {\n   *     await browser.window.maximize();\n   *   }\n   * };\n   */\n  maximize(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Hides the window in the system tray. If the window happens to be in fullscreen mode,\n   * it is restored the normal state then it will be \"iconified\" - minimize or hide the window from the visible screen.\n   *\n   * @example\n   * module.exports = {\n   *  'minimize current window': function (browser) {\n   *     browser.window.minimize(function () {\n   *       console.log('window minimized successfully');\n   *     });\n   *   },\n   *\n   *   'minimize current window using ES6 async/await': async function (browser) {\n   *     await browser.window.minimize();\n   *   }\n   * };\n   */\n  minimize(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Set the current window state to fullscreen, similar to pressing F11 in most browsers.\n   *\n   * @example\n   * module.exports = {\n   *  'make current window fullscreen': function (browser) {\n   *     browser.window.fullscreen(function () {\n   *       console.log('window in fullscreen mode');\n   *     });\n   *   },\n   *\n   *   'make current window fullscreen with ES6 async/await': async function (browser) {\n   *     await browser.window.fullscreen();\n   *   }\n   * };\n   */\n  fullscreen(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Get the coordinates of the top left corner of the current window.\n   *\n   * @example\n   * module.exports = {\n   *   'get current window position': function (browser) {\n   *      browser.window.getPosition(function (result) {\n   *        console.log('Position of current window:', result.value.x, result.value.y);\n   *      });\n   *   },\n   *\n   *   'get current window position using ES6 async/await': async function (browser) {\n   *      const {x, y} = await browser.window.getPosition();\n   *      console.log('Position of current window:', x, y);\n   *   }\n   * };\n   */\n  getPosition(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<WindowPosition>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, WindowPosition>;\n\n  /**\n   * Get the size of the current window in pixels.\n   *\n   * @example\n   * module.exports = {\n   *   'get current window size': function (browser) {\n   *      browser.window.getSize(function (result) {\n   *        console.log('Size of current window:', result.value.width, result.value.height);\n   *      });\n   *   },\n   *\n   *   'get current window size using ES6 async/await': async function (browser) {\n   *      const {width, height} = await browser.window.getSize();\n   *      console.log('Size of current window:', width, height);\n   *   }\n   * };\n   */\n  getSize(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<WindowSize>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, WindowSize>;\n\n  /**\n   * Fetches the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect) - size and position of the current window.\n   *\n   * Its JSON representation is the following:\n   * - `x` - window's screenX attribute;\n   * - `y` - window's screenY attribute;\n   * - `width` - outerWidth attribute;\n   * - `height` - outerHeight attribute.\n   *\n   * All attributes are in CSS pixels.\n   *\n   * @example\n   * module.exports = {\n   *   'get current window rect': function (browser) {\n   *      browser.window.getRect(function (result) {\n   *        console.log('Size of current window:', result.value.width, result.value.height);\n   *        console.log('Position of current window:', result.value.x, result.value.y);\n   *      });\n   *   },\n   *\n   *   'get current window rect using ES6 async/await': async function (browser) {\n   *      const {width, height, x, y} = await browser.window.getRect();\n   *      console.log('Size of current window:', width, height);\n   *      console.log('Position of current window:', x, y);\n   *   }\n   * };\n   */\n  getRect(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<WindowSizeAndPosition>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, WindowSizeAndPosition>;\n\n  /**\n   * Set the position of the current window - move the window to the chosen position.\n   *\n   * @example\n   * module.exports = {\n   *   'set current window position': function (browser) {\n   *      // Move the window to the top left of the primary monitor\n   *      browser.window.setPosition(0, 0, function (result) {\n   *        console.log('window moved successfully');\n   *      });\n   *   },\n   *\n   *   'set current window position using ES6 async/await': async function (browser) {\n   *      // Move the window to the top left of the primary monitor\n   *      await browser.window.setPosition(0, 0);\n   *   }\n   * };\n   */\n  setPosition(\n    x: number,\n    y: number,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Set the size of the current window in CSS pixels.\n   *\n   * @example\n   * module.exports = {\n   *   'set current window size': function (browser) {\n   *      browser.window.setSize(1024, 768, function (result) {\n   *        console.log('window resized successfully');\n   *      });\n   *   },\n   *\n   *   'set current window size using ES6 async/await': async function (browser) {\n   *      await browser.window.setSize(1024, 768);\n   *   }\n   * };\n   *\n   * @alias window.resize\n   */\n  setSize(\n    width: number,\n    height: number,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Set the size of the current window in CSS pixels.\n   *\n   * @example\n   * module.exports = {\n   *   'set current window size': function (browser) {\n   *      browser.window.setSize(1024, 768, function (result) {\n   *        console.log('window resized successfully');\n   *      });\n   *   },\n   *\n   *   'set current window size using ES6 async/await': async function (browser) {\n   *      await browser.window.setSize(1024, 768);\n   *   }\n   * };\n   *\n   * @alias window.setSize\n   */\n  resize(\n    width: number,\n    height: number,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n\n  /**\n   * Change the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect) - size and position of the current window.\n   *\n   * Its JSON representation is the following:\n   * - `x` - window's screenX attribute;\n   * - `y` - window's screenY attribute;\n   * - `width` - outerWidth attribute;\n   * - `height` - outerHeight attribute.\n   *\n   * All attributes are in CSS pixels.\n   *\n   * To change the window rect, you can either specify `width` and `height` together, `x` and `y` together, or all properties together.\n   *\n   * @example\n   * module.exports = {\n   *   'set current window rect': function (browser) {\n   *      // Change the screenX and screenY attributes of the window rect.\n   *      browser.window.setRect({x: 500, y: 500});\n   *\n   *      // Change the outerWidth and outerHeight attributes of the window rect.\n   *      browser.window.setRect({width: 600, height: 300});\n   *   },\n   *\n   *   'set current window rect using ES6 async/await': async function (browser) {\n   *      // Change all attributes of the window rect at once.\n   *      await browser.window.setRect({\n   *        width: 600,\n   *        height: 300,\n   *        x: 100,\n   *        y: 100\n   *      });\n   *   }\n   * };\n   */\n  setRect(\n    options: WindowSize | WindowPosition | WindowSizeAndPosition,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<IfUnknown<ReturnType, this>, null>;\n}\n\nexport interface WebDriverProtocol\n  extends WebDriverProtocolSessions,\n  WebDriverProtocolNavigation,\n  WebDriverProtocolCommandContexts,\n  WebDriverProtocolElements,\n  WebDriverProtocolElementState,\n  WebDriverProtocolElementInteraction,\n  WebDriverProtocolElementLocation,\n  WebDriverProtocolDocumentHandling,\n  WebDriverProtocolCookies,\n  WebDriverProtocolUserActions,\n  WebDriverProtocolUserPrompts,\n  WebDriverProtocolScreenCapture,\n  WebDriverProtocolMobileRelated { }\n\nexport interface NightwatchServerStatusResult {\n  build: { version: string; revision: string; time: string };\n  status: { arch: string; name: string; version: string };\n}\n\nexport interface WebDriverProtocolSessions {\n  /**\n   * Get info about, delete or create a new session. Defaults to the current session.\n   *\n   * @example\n   * this.demoTest = function (browser) {\n   *    browser.session(function(result) {\n   *      console.log(result.value);\n   *    });\n   *    //\n   *    browser.session('delete', function(result) {\n   *      console.log(result.value);\n   *    });\n   *    //\n   *    browser.session('delete', '12345-abc', function(result) {\n   *      console.log(result.value);\n   *    });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/session.html#apimethod-container\n   */\n  session(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<Record<string, any>>\n    ) => void\n  ): Awaitable<this, Record<string, any>>;\n  session(\n    actionOrSessionId: \"get\" | \"post\" | \"delete\" | \"GET\" | \"POST\" | \"DELETE\" | string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<Record<string, any>>\n    ) => void,\n  ): Awaitable<this, Record<string, any>>;\n  session(\n    action: \"get\" | \"post\" | \"delete\" | \"GET\" | \"POST\" | \"DELETE\",\n    sessionId: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<Record<string, any>>\n    ) => void,\n  ): Awaitable<this, Record<string, any>>;\n\n  /**\n   * Returns a list of the currently active sessions.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.sessions(function(result) {\n   *      console.log(result.value);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/sessions.html\n   */\n  sessions(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<Array<Record<string, any>>>\n    ) => void\n  ): Awaitable<this, Array<Record<string, any>>>;\n\n  /**\n   * Configure the amount of time that a particular type of operation can execute for before they are aborted and a |Timeout| error is returned to the client.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.timeouts('script', 10000, function(result) {\n   *      console.log(result);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/timeouts.html\n   */\n  timeouts(\n    typeOfOperation: 'script' | 'implicit' | 'pageLoad',\n    ms: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void,\n  ): Awaitable<this, null>;\n  timeouts(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<{ script: number, implicit: number, pageLoad: number }>\n    ) => void\n  ): Awaitable<this, { script: number, implicit: number, pageLoad: number }>;\n\n  /**\n   * Set the amount of time, in milliseconds, that asynchronous scripts executed by `.executeAsync` are permitted to run before they are aborted and a |Timeout| error is returned to the client.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.timeoutsAsyncScript(10000, function(result) {\n   *      console.log(result);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/timeoutsAsyncScript.html\n   */\n  timeoutsAsyncScript(\n    ms: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Set the amount of time the driver should wait when searching for elements. If this command is never sent, the driver will default to an implicit wait of 0ms.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.timeoutsImplicitWait(10000, function(result) {\n   *      console.log(result);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/timeoutsImplicitWait.html\n   */\n  timeoutsImplicitWait(\n    ms: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Query the server's current status.\n   *\n   * @see https://nightwatchjs.org/api/status.html\n   */\n  status(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchServerStatusResult>,\n    ) => void\n  ): Awaitable<this, NightwatchServerStatusResult>;\n\n  /**\n   * Gets the text of the log type specified. To find out the available log types, use `.getLogTypes()`.\n   *\n   * Returns a [log entry JSON object](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#log-entry-json-object).\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.sessionLog('client', function(result) {\n   *      console.log(result.value);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/sessionLog.html\n   */\n  sessionLog(\n    typeString: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<NightwatchLogEntry[]>) => void\n  ): Awaitable<this, NightwatchLogEntry[]>;\n\n  /**\n   * Gets an array of strings for which log types are available. This methods returns the entire WebDriver response, if you are only interested in the logs array, use `.getLogTypes()` instead.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.sessionLogTypes(function(result) {\n   *      console.log(result.value);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/sessionLogTypes.html\n   */\n  sessionLogTypes(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchLogTypes[]>\n    ) => void\n  ): Awaitable<this, NightwatchLogTypes[]>;\n}\n\nexport interface WebDriverProtocolNavigation {\n  /**\n   * Retrieve the URL of the current page or navigate to a new URL.\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test' : function(browser) {\n   *     browser.url(function(result) {\n   *       // return the current url\n   *       console.log(result);\n   *     });\n   *     //\n   *     // navigate to new url:\n   *     browser.url('{URL}');\n   *     //\n   *     //\n   *     // navigate to new url:\n   *     browser.url('{URL}', function(result) {\n   *       console.log(result);\n   *     });\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/url.html\n   */\n  url(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n  url(\n    url: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Navigate backwards in the browser history, if possible.\n   *\n   * @see https://nightwatchjs.org/api/back.html\n   */\n  back(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Navigate forwards in the browser history, if possible.\n   *\n   * @see https://nightwatchjs.org/api/forward.html\n   */\n  forward(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Refresh the current page.\n   *\n   * @see https://nightwatchjs.org/api/refresh.html\n   */\n  refresh(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Get the current page title.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.title(function(result) {\n   *      console.log(result.value);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/title.html\n   */\n  title(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n}\n\nexport interface WebDriverProtocolCommandContexts {\n  /**\n   * Retrieve the current window handle.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.windowHandle(function(result) {\n   *      console.log(result.value);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/windowHandle.html\n   *\n   * @deprecated In favour of `.window.getHandle()`.\n   */\n  windowHandle(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Retrieve the list of all window handles available to the session.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.windowHandles(function(result) {\n   *      // An array of window handles.\n   *      console.log(result.value);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/windowHandles.html\n   *\n   * @deprecated In favour of `.window.getAllHandles()`.\n   */\n  windowHandles(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string[]>\n    ) => void\n  ): Awaitable<this, string[]>;\n\n  /**\n   * Increases the window to the maximum available size without going full-screen.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.windowMaximize('current', function(result) {\n   *      console.log(result);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/windowMaximize.html\n   *\n   * @deprecated In favour of `.window.maximize()`.\n   */\n  windowMaximize(\n    handleOrName?: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Change or get the position of the specified window. If the second argument is a function it will be used as a callback and\n   * the call will perform a get request to retrieve the existing window position.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *\n   *    // Change the position of the specified window.\n   *    // If the :windowHandle URL parameter is \"current\", the currently active window will be moved.\n   *    browser.windowPosition('current', 0, 0, function(result) {\n   *      console.log(result);\n   *    });\n   *\n   *    // Get the position of the specified window.\n   *    // If the :windowHandle URL parameter is \"current\", the position of the currently active window will be returned.\n   *    browser.windowPosition('current', function(result) {\n   *      console.log(result.value);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/windowPosition.html\n   *\n   * @deprecated In favour of `.window.getPosition()` and `.window.setPosition()`.\n   */\n  windowPosition(\n    windowHandle: string,\n    offsetX: number,\n    offsetY: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  windowPosition(\n    windowHandle: string,\n    callback: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<WindowPosition>\n    ) => void\n  ): Awaitable<this, WindowPosition>;\n\n  /**\n   * Change or get the size of the specified window. If the second argument is a function it will be used as a callback and the call will perform a get request to retrieve the existing window size.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *\n   *    // Return the size of the specified window. If the :windowHandle URL parameter is \"current\", the size of the currently active window will be returned.\n   *    browser.windowSize('current', function(result) {\n   *      console.log(result.value);\n   *    });\n   *\n   *    // Change the size of the specified window.\n   *    // If the :windowHandle URL parameter is \"current\", the currently active window will be resized.\n   *    browser.windowSize('current', 300, 300, function(result) {\n   *      console.log(result.value);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/windowSize.html\n   *\n   * @deprecated In favour of `.window.getSize()` and `.window.setSize()`.\n   */\n  windowSize(\n    windowHandle: string,\n    width: number,\n    height: number,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  windowSize(\n    windowHandle: string,\n    callback: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<WindowSizeAndPosition>\n    ) => void\n  ): Awaitable<this, WindowSizeAndPosition>;\n\n  /**\n   * Change or get the [window rect](https://w3c.github.io/webdriver/#dfn-window-rect).\n   * This is defined as a dictionary of the `screenX`, `screenY`, `outerWidth` and `outerHeight` attributes of the window.\n   *\n   * Its JSON representation is the following:\n   * - `x` - window's screenX attribute;\n   * - `y` - window's screenY attribute;\n   * - `width` - outerWidth attribute;\n   * - `height` - outerHeight attribute.\n   *\n   * All attributes are in in CSS pixels. To change the window react, you can either specify `width` and `height`, `x` and `y` or all properties together.\n   *\n   * @example\n   * module.exports = {\n   *   'demo test .windowRect()': function(browser) {\n   *\n   *      // Change the screenX and screenY attributes of the window rect.\n   *      browser.windowRect({x: 500, y: 500});\n   *\n   *      // Change the width and height attributes of the window rect.\n   *      browser.windowRect({width: 600, height: 300});\n   *\n   *      // Retrieve the attributes\n   *      browser.windowRect(function(result) {\n   *        console.log(result.value);\n   *      });\n   *   },\n   *\n   *   'windowRect ES6 demo test': async function(browser) {\n   *      const resultValue = await browser.windowRect();\n   *      console.log('result value', resultValue);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/windowRect.html\n   *\n   * @deprecated In favour of `.window.getRect()` and `.window.setRect()`.\n   */\n  windowRect(\n    options: { width?: number; height?: number; x?: number; y?: number },\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n  windowRect(\n    options: null,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<WindowSizeAndPosition>\n    ) => void,\n  ): Awaitable<this, WindowSizeAndPosition>;\n\n  /**\n   * Change focus to another frame on the page. If the frame id is missing or null, the server should switch to the page's default content.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.frame('<ID>', function(result) {\n   *      console.log(result);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/frame.html\n   */\n  frame(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void,\n  ): Awaitable<this, null>;\n  frame(\n    frameId: WebElement | string | number | null,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void,\n  ): Awaitable<this, null>;\n\n  /**\n   * Change focus to the parent context. If the current context is the top level browsing context, the context remains unchanged.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.frameParent(function(result) {\n   *      console.log(result);\n   *    });\n   *  }\n   *\n   * @see https://nightwatchjs.org/api/frameParent.html\n   *\n   * @since v0.4.8\n   */\n  frameParent(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n}\n\nexport interface WebDriverProtocolElements {\n  /**\n   * Provides access to Nightwatch new element API.\n   *\n   * @example\n   * module.exports = {\n   *   'new element api': function (browser) {\n   *     // Using element as function.\n   *     const button1 = browser.element('button.submit-form');\n   *\n   *     // Using the find method of the element namespace.\n   *     const button2 = browser.element.find('button.submit-form');\n   *     // Searching for the icon element inside the .submit-form button.\n   *     const icon = button2.find('i');\n   *\n   *     // Use an object to customise locating behaviour.\n   *     const main = browser.element({ selector: 'main', locateStrategy: 'css selector' });\n   *   },\n   *\n   *   'new element api async': function (browser) {\n   *     // button is the WebElement object.\n   *     const button = await browser.element('button.submit-form');\n   *   },\n   *\n   *   'with backward compatibility': function (browser) {\n   *     // for backward compatibility\n   *     browser.element('css selector', 'body');\n   *   }\n   * }\n   */\n  element: ElementFunction;\n\n  /**\n   * Search for multiple elements on the page, starting from the document root. The located elements will be returned as web element JSON objects.\n   * First argument to be passed is the locator strategy, which is detailed on the [WebDriver docs](https://www.w3.org/TR/webdriver/#locator-strategies).\n   *\n   * * The locator strategy can be one of:\n   * - `css selector`\n   * - `link text`\n   * - `partial link text`\n   * - `tag name`\n   * - `xpath`\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test' : function(browser) {\n   *     browser.elements('css selector', 'ul li', function(result) {\n   *       console.log(result.value)\n   *     });\n   *   },\n   *\n   *   'es6 async demo Test': async function(browser) {\n   *     const result = await browser.elements('css selector', 'ul li');\n   *     console.log('result value is:', result);\n   *   },\n   *\n   *   'page object demo Test': function (browser) {\n   *      var nightwatch = browser.page.nightwatch();\n   *      nightwatch\n   *        .navigate()\n   *        .assert.titleContains('Nightwatch.js');\n   *\n   *      nightwatch.api.elements('@featuresList', function(result) {\n   *        console.log(result);\n   *      });\n   *\n   *      browser.end();\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/elements.html\n   */\n  elements(\n    using: LocateStrategy,\n    value: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<ElementResult[]>\n    ) => void\n  ): Awaitable<this, ElementResult[]>;\n\n  /**\n   * Search for an element on the page, starting from the identified element. The located element will be returned as a Web Element JSON object.\n   *\n   * This command operates on a protocol level and requires a [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements).\n   * Read more on [Element retrieval](https://www.w3.org/TR/webdriver1/#element-retrieval) on the W3C WebDriver spec page.\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test' : function(browser) {\n   *     browser.findElement('.some-element', (result) => {\n   *       this.elementIdElement(result.value.getId(), 'css selector', '.new-element', function(result) {\n   *         console.log(result.value);\n   *       });\n   *     });\n   *   },\n   *\n   *   'es6 async demo Test': async function(browser) {\n   *     const elementObject = await browser.findElement('.some-element');\n   *     const result = await browser.elementIdElement(elementId.getId(), 'css selector', '.new-element');\n   *     console.log(result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/elementIdElement.html\n   */\n  elementIdElement(\n    id: string,\n    using: LocateStrategy,\n    value: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<ElementResult | []>\n    ) => void\n  ): Awaitable<this, ElementResult | []>;\n\n  /**\n   * Search for multiple elements on the page, starting from the identified element. The located element will be returned as a web element JSON objects.\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test' : function(browser) {\n   *     browser.findElement('#main', (result) => {\n   *       browser.elementIdElements(result.value.getId(), 'css selector', 'ul li', function(result) {\n   *         console.log(result.value)\n   *       });\n   *     });\n   *   },\n   *\n   *   'es6 async demo Test': async function(browser) {\n   *     const elementObject = await browser.findElement('#main');\n   *     const result = await browser.elementIdElements(elementObject.getId(), 'css selector', 'ul li');\n   *     console.log(result);\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/elementIdElements.html\n   */\n  elementIdElements(\n    id: string,\n    using: LocateStrategy,\n    value: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<ElementResult[]>\n    ) => void\n  ): Awaitable<this, ElementResult[]>;\n\n  /**\n   * Move to the element and performs a double-click in the middle of the given element if\n   * element is given else double-clicks at the current mouse coordinates (set by `.moveTo()`).\n   *\n   */\n  elementIdDoubleClick(\n    webElementId: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Retrieve the value of a specified DOM property for the given element.\n   * For all the available DOM element properties, consult the [Element doc at MDN](https://developer.mozilla.org/en-US/docs/Web/API/element).\n   */\n  elementIdProperty(\n    webElementId: string,\n    DOMPropertyName: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<any>\n    ) => void\n  ): Awaitable<this, any>;\n\n  /**\n   * Test if two web element IDs refer to the same DOM element.\n   *\n   * This command is __deprecated__ and is only available on the [JSON Wire protocol](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidelementidequalsother)\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test' : function(browser) {\n   *     browser.elementIdEquals('<ID-1>', '<ID-2>', function(result) {\n   *       console.log(result.value)\n   *     });\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/elementIdEquals.html\n   *\n   * @deprecated In favour of WebElement.equals(a, b) from Selenium Webdriver.\n   */\n  elementIdEquals(\n    id: string,\n    otherId: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   * Get the element on the page that currently has focus.\n   * The element will be returned as a [Web Element](https://www.w3.org/TR/webdriver1/#dfn-web-elements) id.\n   *\n   * @example\n   * module.exports = {\n   *  'demo Test' : function(browser) {\n   *     browser.elementActive(function(result) {\n   *       console.log(result.value)\n   *     });\n   *   }\n   * }\n   *\n   * @see https://nightwatchjs.org/api/elementActive.html\n   */\n  elementActive(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n}\n\nexport interface WebDriverProtocolElementState {\n  /**\n   * Get the value of an element's attribute.\n   *\n   * @see https://nightwatchjs.org/api/elementIdAttribute.html\n   */\n  elementIdAttribute(\n    id: string,\n    attributeName: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string | null>\n    ) => void\n  ): Awaitable<this, string | null>;\n\n  /**\n   * Retrieve the computed value of the given CSS property of the given element.\n   *\n   * The CSS property to query should be specified using the CSS property name, not the JavaScript property name (e.g. background-color instead of backgroundColor).\n   *\n   * @see https://nightwatchjs.org/api/elementIdCssProperty.html\n   */\n  elementIdCssProperty(\n    id: string,\n    cssPropertyName: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Determine if an element is currently displayed.\n   *\n   * @see https://nightwatchjs.org/api/elementIdDisplayed.html\n   */\n  elementIdDisplayed(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   * Determine if an element is currently enabled.\n   *\n   * @see https://nightwatchjs.org/api/elementIdEnabled.html\n   */\n  elementIdEnabled(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   * Retrieve the qualified tag name of the given element.\n   *\n   * @see https://nightwatchjs.org/api/elementIdName.html\n   */\n  elementIdName(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Determine if an OPTION element, or an INPUT element of type checkbox or radio button is currently selected.\n   *\n   * @see https://nightwatchjs.org/api/elementIdSelected.html\n   */\n  elementIdSelected(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<boolean>\n    ) => void\n  ): Awaitable<this, boolean>;\n\n  /**\n   * Determine an element's size in pixels. The size will be returned as a JSON object with width and height properties.\n   *\n   * @see https://nightwatchjs.org/api/elementIdSize.html\n   *\n   * @deprecated In favour of .getElementRect()\n   */\n  elementIdSize(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchSizeAndPosition>\n    ) => void\n  ): Awaitable<this, NightwatchSizeAndPosition>;\n\n  /**\n   * Returns the visible text for the element.\n   *\n   * @see https://nightwatchjs.org/api/elementIdText.html\n   */\n  elementIdText(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n}\n\nexport interface WebDriverProtocolElementInteraction {\n  /**\n   * Scrolls into view a submittable element excluding buttons or editable element, and then attempts to clear its value, reset the checked state, or text content.\n   *\n   * @example\n   * browser.elementIdClear(elementId);\n   *\n   * @see https://nightwatchjs.org/api/elementIdClear.html\n   */\n  elementIdClear(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Scrolls into view the element and clicks the in-view center point.\n   * If the element is not pointer-interactable,\n   * an <code>element not interactable</code> error is returned.\n   *\n   * @example\n   * browser.elementIdClick(elementId);\n   *\n   * @see https://nightwatchjs.org/api/elementIdClick.html\n   */\n  elementIdClick(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Scrolls into view the form control element and then sends the provided keys to the element, or returns the current value of the element.\n   * In case the element is not keyboard interactable, an <code>element not interactable error</code> is returned.\n   *\n   * @see https://nightwatchjs.org/api/elementIdValue.html\n   *\n   * @deprecated In favour of .getValue() and .setValue()\n   */\n  elementIdValue(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n  elementIdValue(\n    id: string,\n    value: string | string[],\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Send a sequence of key strokes to the active element. The sequence is defined in the same format as the `sendKeys` command.\n   * An object map with available keys and their respective UTF-8 characters, as defined on [W3C WebDriver draft spec](https://www.w3.org/TR/webdriver/#character-types),\n   * is loaded onto the main Nightwatch instance as `client.Keys`.\n   *\n   * Rather than the `setValue`, the modifiers are not released at the end of the call. The state of the modifier keys is kept between calls,\n   * so mouse interactions can be performed while modifier keys are depressed.\n   *\n   * Since v2.0, this command is deprecated. It is only available on older JSONWire-based drivers.\n   * Please use the new [User Actions API](https://nightwatchjs.org/api/useractions/).\n   *\n   * @example\n   * browser\n   * .keys(browser.Keys.CONTROL) // hold down CONTROL key\n   * .click('#element')\n   * .keys(browser.Keys.NULL) // release all keys\n   *\n   * @see https://nightwatchjs.org/api/keys.html\n   *\n   * @deprecated Please use the new [User Actions API](https://nightwatchjs.org/api/useractions/) instead.\n   */\n  keys(\n    keysToSend: string | string[],\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Submit a FORM element. The submit command may also be applied to any element that is a descendant of a FORM element.\n   *\n   * @example\n   * browser.submit(elementID);\n   *\n   * @see https://nightwatchjs.org/api/submit.html\n   */\n  submit(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n}\n\nexport interface WebDriverProtocolElementLocation {\n  /**\n   * Determine an element's location on the page. The point (0, 0) refers to the upper-left corner of the page.\n   *\n   * The element's coordinates are returned as a JSON object with x and y properties.\n   *\n   * @see https://nightwatchjs.org/api/elementIdLocation.html\n   *\n   * @deprecated In favour of .getElementRect()\n   */\n  elementIdLocation(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchSizeAndPosition>\n    ) => void\n  ): Awaitable<this, NightwatchSizeAndPosition>;\n\n  /**\n   * Determine an element's location on the screen once it has been scrolled into view.\n   *\n   * @see https://nightwatchjs.org/api/elementIdLocationInView.html#apimethod-container\n   *\n   * @deprecated This is JSON Wire Protocol command and is no longer supported.\n   */\n  elementIdLocationInView(\n    id: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<NightwatchPosition>\n    ) => void\n  ): Awaitable<this, NightwatchPosition>;\n}\n\nexport interface WebDriverProtocolDocumentHandling {\n  /**\n   * Returns a string serialisation of the DOM of the current page.\n   *\n   * @example\n   * browser.source();\n   *\n   * @see https://nightwatchjs.org/api/source.html\n   *\n   * @deprecated In favour of `.document.source()`.\n   */\n  source(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous.\n   * The script argument defines the script to execute in the form of a function body. The value returned by that function will be returned to the client.\n   *\n   * The function will be invoked with the provided args array and the values may be accessed via the arguments object in the order specified.\n   *\n   * Under the hood, if the `body` param is a function it is converted to a string with `<function>.toString()`. Any references to your current scope are ignored.\n   *\n   * To ensure cross-browser compatibility, the specified function should not be in ES6 format (i.e. `() => {}`).\n   * If the execution of the function fails, the first argument of the callback contains error information.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.execute(function(imageData: string) {\n   *      // resize operation\n   *      return true;\n   *    }, [imageData], function(result) {\n   *      // result.value === true\n   *    });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/execute.html#apimethod-container\n   *\n   * @alias executeScript\n   */\n  execute<ReturnValue>(\n    body: ExecuteScriptFunction<[], ReturnValue> | string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<VoidToNull<ReturnValue>>\n    ) => void,\n  ): Awaitable<this, VoidToNull<ReturnValue>>;\n  execute<ArgType extends any[], ReturnValue>(\n    body: ExecuteScriptFunction<ArgType, ReturnValue> | string,\n    args: ArgType,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<VoidToNull<ReturnValue>>\n    ) => void,\n  ): Awaitable<this, VoidToNull<ReturnValue>>;\n\n  /**\n   * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous.\n   * The script argument defines the script to execute in the form of a function body. The value returned by that function will be returned to the client.\n   *\n   * The function will be invoked with the provided args array and the values may be accessed via the arguments object in the order specified.\n   *\n   * Under the hood, if the `body` param is a function it is converted to a string with `<function>.toString()`. Any references to your current scope are ignored.\n   *\n   * To ensure cross-browser compatibility, the specified function should not be in ES6 format (i.e. `() => {}`).\n   * If the execution of the function fails, the first argument of the callback contains error information.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.executeScript(function(imageData: string) {\n   *      // resize operation\n   *      return true;\n   *    }, [imageData], function(result) {\n   *      // result.value === true\n   *    });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/execute.html#apimethod-container\n   *\n   * @alias execute\n   */\n  executeScript<ReturnValue>(\n    body: ExecuteScriptFunction<[], ReturnValue> | string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<VoidToNull<ReturnValue>>\n    ) => void,\n  ): Awaitable<this, VoidToNull<ReturnValue>>;\n  executeScript<ArgType extends any[], ReturnValue>(\n    body: ExecuteScriptFunction<ArgType, ReturnValue> | string,\n    args: ArgType,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<VoidToNull<ReturnValue>>\n    ) => void,\n  ): Awaitable<this, VoidToNull<ReturnValue>>;\n\n  /**\n   *\n   * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame.\n   * The executed script is assumed to be asynchronous.\n   *\n   * The function to be injected receives the `done` callback as argument which needs to be called\n   * when the asynchronous operation finishes. The value passed to the `done` callback is returned to the client.\n   * Additional arguments for the injected function may be passed as a non-empty array which\n   * will be passed before the `done` callback.\n   *\n   * Asynchronous script commands may not span page loads. If an unload event is fired\n   *  while waiting for the script result, an error will be returned.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.executeAsyncScript(function(done: (result: true) => void) {\n   *      setTimeout(function() {\n   *        done(true);\n   *      }, 500);\n   *    }, function(result) {\n   *      // result.value === true\n   *    });\n   *\n   *    browser.executeAsyncScript(function(arg1: string, arg2: number, done: (result: string) => void) {\n   *      setTimeout(function() {\n   *        done(arg1);\n   *      }, 500);\n   *    }, [arg1, arg2], function(result) {\n   *      // result.value === arg1\n   *    });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/executeAsyncScript.html\n   *\n   * @alias executeAsync\n   */\n  executeAsyncScript<ReturnValue>(\n    script: ExecuteAsyncScriptFunction<[], ReturnValue> | string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<ReturnValue>\n    ) => void,\n  ): Awaitable<this, ReturnValue>;\n  executeAsyncScript<ArgType extends any[], ReturnValue>(\n    script: ExecuteAsyncScriptFunction<ArgType, ReturnValue> | string,\n    args: ArgType,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<ReturnValue>\n    ) => void,\n  ): Awaitable<this, ReturnValue>;\n\n  /**\n   * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be asynchronous.\n   *\n   * The function to be injected receives the `done` callback as argument which needs to be called when the asynchronous operation finishes.\n   * The value passed to the `done` callback is returned to the client.\n   * Additional arguments for the injected function may be passed as a non-empty array which will be passed before the `done` callback.\n   *\n   * Asynchronous script commands may not span page loads. If an unload event is fired while waiting for the script result, an error will be returned.\n   *\n   * @example\n   *  this.demoTest = function (browser) {\n   *    browser.executeAsync(function(done: (result: true) => void) {\n   *      setTimeout(function() {\n   *        done(true);\n   *      }, 500);\n   *    }, function(result) {\n   *      // result.value === true\n   *    });\n   *\n   *    browser.executeAsync(function(arg1: string, arg2: number, done: (result: string) => void) {\n   *      setTimeout(function() {\n   *        done(arg1);\n   *      }, 500);\n   *    }, [arg1, arg2], function(result) {\n   *      // result.value === arg1\n   *    });\n   * }\n   *\n   * @see https://nightwatchjs.org/api/executeAsyncScript.html\n   *\n   * @alias executeAsyncScript\n   */\n  executeAsync<ReturnValue>(\n    script: ExecuteAsyncScriptFunction<[], ReturnValue> | string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<ReturnValue>\n    ) => void,\n  ): Awaitable<this, ReturnValue>;\n  executeAsync<ArgType extends any[], ReturnValue>(\n    script: ExecuteAsyncScriptFunction<ArgType, ReturnValue> | string,\n    args: ArgType,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<ReturnValue>\n    ) => void,\n  ): Awaitable<this, ReturnValue>;\n}\n\nexport interface WebDriverProtocolCookies {\n  /**\n   * Retrieve or delete all cookies visible to the current page or set a cookie. Normally this shouldn't be used directly, instead the cookie convenience methods should be used:\n   * <code>getCookie</code>, <code>getCookies</code>, <code>setCookie</code>, <code>deleteCookie</code>, <code>deleteCookies</code>.\n   *\n   * @see getCookies\n   * @see getCookie\n   * @see setCookie\n   * @see deleteCookie\n   * @see deleteCookies\n   *\n   * @deprecated\n   */\n  cookie(\n    method: \"GET\" | \"DELETE\",\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<Cookie[] | null>) => void\n  ): Awaitable<this, Cookie[] | null>;\n  cookie(\n    method: \"POST\",\n    cookie: Cookie,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void\n  ): Awaitable<this, null>;\n  cookie(\n    method: \"DELETE\",\n    cookieName: string,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void\n  ): Awaitable<this, null>;\n}\n\nexport interface WebDriverProtocolUserActions {\n  /**\n   * Release the depressed left mouse button at the current mouse coordinates (set by `.moveTo()`).\n   *\n   * @see https://nightwatchjs.org/api/releaseMouseButton.html#apimethod-container\n   */\n  releaseMouseButton(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Click at the current mouse coordinates (set by `.moveTo()`).\n   *\n   * The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button.\n   *\n   * @see https://nightwatchjs.org/api/mouseButtonClick.html\n   *\n   * @deprecated Please use the new [User Actions API](https://nightwatchjs.org/api/useractions/) instead.\n   */\n  mouseButtonClick(\n    button: 0 | 1 | 2 | 'left' | 'middle' | 'right',\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Click and hold the left mouse button (at the coordinates set by the last `moveTo` command). Note that the next mouse-related command that should follow is `mouseButtonUp` .\n   * Any other mouse command (such as click or another call to buttondown) will yield undefined behaviour.\n   *\n   * Can be used for implementing drag-and-drop. The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button,\n   * and if you don't pass in a button but do pass in a callback, it will handle it correctly.\n   *\n   * **Since v2.0, this command is deprecated.** It is only available on older JSONWire-based drivers.\n   * Please use the new [User Actions API](/api/useractions/).\n   *\n   * @see https://nightwatchjs.org/api/mouseButtonDown.html\n   *\n   * @deprecated Please use the new [User Actions API](https://nightwatchjs.org/api/useractions/) instead.\n   */\n  mouseButtonDown(\n    button: 0 | 1 | 2 | 'left' | 'middle' | 'right',\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Releases the mouse button previously held (where the mouse is currently at). Must be called once for every `mouseButtonDown` command issued.\n   *\n   * Can be used for implementing drag-and-drop. The button can be (0, 1, 2) or ('left', 'middle', 'right'). It defaults to left mouse button,\n   * and if you don't pass in a button but do pass in a callback, it will handle it correctly.\n   *\n   * **Since v2.0, this command is deprecated.** It is only available on older JSONWire-based drivers.\n   * Please use the new [User Actions API](/api/useractions/).\n   *\n   * @see https://nightwatchjs.org/api/mouseButtonUp.html\n   *\n   * @deprecated Please use the new [User Actions API](https://nightwatchjs.org/api/useractions/) instead.\n   */\n  mouseButtonUp(\n    button: 0 | 1 | 2 | 'left' | 'middle' | 'right',\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Move the mouse by an offset of the specified [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) or relative to the current mouse cursor, if no element is specified.\n   * If an element is provided but no offset, the mouse will be moved to the center of the element.\n   *\n   * If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view.\n   *\n   * @example\n   * this.demoTest = function (browser) {\n   *   browser.moveTo(null, 110, 100);\n   * };\n   *\n   * @see https://nightwatchjs.org/api/moveTo.html#apimethod-container\n   */\n  moveTo(\n    elementId: string | null,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<this, null>;\n  moveTo(\n    xoffset: number,\n    yoffset: number,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<this, null>;\n  moveTo(\n    elementId: string | null,\n    xoffset: number,\n    yoffset: number,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<null>) => void,\n  ): Awaitable<this, null>;\n}\n\nexport interface WebDriverProtocolUserPrompts {\n  /**\n   * Accepts the currently displayed alert dialog. Usually, this is equivalent to clicking on the 'OK' button in the dialog.\n   *\n   * @example\n   * browser.acceptAlert()\n   *\n   * @see https://nightwatchjs.org/api/acceptAlert.html\n   *\n   * @deprecated In favour of `.alerts.accept()`.\n   */\n  acceptAlert(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Dismisses the currently displayed alert dialog. For confirm() and prompt() dialogs, this is equivalent to clicking the 'Cancel' button.\n   *\n   * For alert() dialogs, this is equivalent to clicking the 'OK' button.\n   *\n   * @example\n   * browser.dismissAlert();\n   *\n   * @see https://nightwatchjs.org/api/dismissAlert.html\n   *\n   * @deprecated In favour of `.alerts.dismiss()`.\n   */\n  dismissAlert(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n\n  /**\n   * Gets the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog.\n   *\n   * @example\n   * browser.getAlertText();\n   *\n   * @see https://nightwatchjs.org/api/getAlertText.html\n   *\n   * @deprecated In favour of `.alerts.getText()`.\n   */\n  getAlertText(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string>\n    ) => void\n  ): Awaitable<this, string>;\n\n  /**\n   * Sends keystrokes to a JavaScript prompt() dialog.\n   *\n   * @example\n   * browser.setAlertText('randomalert');\n   *\n   * @see https://nightwatchjs.org/api/setAlertText.html\n   *\n   * @deprecated In favour of `.alerts.setText()`.\n   */\n  setAlertText(\n    value: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n}\n\nexport interface WebDriverProtocolScreenCapture {\n  /**\n   * Take a screenshot of the current page.\n   *\n   * @example\n   * browser.screenshot(true);\n   */\n  screenshot(\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void,\n  ): Awaitable<this, string>;\n  screenshot(\n    log_screenshot_data: boolean,\n    callback?: (this: NightwatchAPI, result: NightwatchCallbackResult<string>) => void,\n  ): Awaitable<this, string>;\n}\n\nexport interface WebDriverProtocolMobileRelated {\n  /**\n   * Get the current browser orientation.\n   *\n   * @example\n   * browser.getOrientation()\n   */\n  getOrientation(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<'LANDSCAPE' | 'PORTRAIT'>\n    ) => void\n  ): Awaitable<this, 'LANDSCAPE' | 'PORTRAIT'>;\n\n  /**\n   * Sets the browser orientation.\n   *\n   * @example\n   * browser.setOrientation(orientation)\n   */\n  setOrientation(\n    orientation: 'LANDSCAPE' | 'PORTRAIT',\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<'LANDSCAPE' | 'PORTRAIT'>\n    ) => void\n  ): Awaitable<this, 'LANDSCAPE' | 'PORTRAIT'>;\n\n  /**\n   * Get a list of the available contexts.\n   *\n   * @example\n   * browser.contexts();\n   *\n   * Used by Appium when testing hybrid mobile web apps. More info here: https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/hybrid.md.\n   */\n  contexts(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string[]>\n    ) => void\n  ): Awaitable<this, string[]>;\n\n  /**\n   * Get current context.\n   *\n   * @example\n   * browser.currentContext();\n   */\n  currentContext(\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<string | null>\n    ) => void\n  ): Awaitable<this, string | null>;\n\n  /**\n   * Sets the context.\n   *\n   * @example\n   * browser.setContext(context);\n   */\n  setContext(\n    context: string,\n    callback?: (\n      this: NightwatchAPI,\n      result: NightwatchCallbackResult<null>\n    ) => void\n  ): Awaitable<this, null>;\n}\n\n// namespaced api\nexport const browser: NightwatchAPI;\nexport const app: NightwatchAPI;\n\nexport const appium: AppiumCommands;\nexport const cookies: CookiesNsCommands;\nexport const alerts: AlertsNsCommands;\nexport const document: DocumentNsCommands;\nexport const window: WindowNsCommands;\nexport const firefox: FirefoxNsCommands;\nexport const chrome: ChromeNsCommands;\n\nexport const assert: Assert;\nexport const verify: Assert;\nexport const expect: Expect;\n\nexport const element: ElementFunction;\n\ndeclare const _default: Nightwatch;\nexport default _default;\n\ndeclare global {\n  const browser: NightwatchBrowser;\n  const app: NightwatchAPI;\n  const element: typeof globalElement;\n  const by: typeof SeleniumBy;\n  const By: typeof SeleniumBy;\n  const ensure: Ensure;\n  const expect: Expect;\n  const locateWith: typeof seleniumLocateWith;\n}\n"
  },
  {
    "path": "types/nightwatch-options.d.ts",
    "content": "import {NightwatchDesiredCapabilities} from './desired-capabilities';\nimport {NightwatchGlobals} from './globals';\n\nexport interface NightwatchTestRunner {\n  type?: string;\n  options?: {\n    ui?: string;\n    feature_path?: string;\n    auto_start_session?: boolean;\n    parallel?: number;\n    reporter?: string;\n    reporterOptions?: { [key: string]: any };\n  };\n}\n\nexport interface NightwatchTestWorker {\n  enabled: boolean;\n  workers?: 'auto' | number;\n  node_options?: string | string[];\n}\n\nexport interface NightwatchScreenshotOptions {\n\tenabled: boolean;\n\tfilename_format?: (failureData: {\n\t\ttestSuite: string;\n\t\ttestCase: string;\n\t\tisError: boolean;\n\t\tdateObject: Date;\n\t}) => string;\n\ton_failure?: boolean;\n\ton_error?: boolean;\n\tpath?: string;\n}\n\nexport interface NightwatchTestSettingGeneric {\n\t/**\n\t * A url which can be used later in the tests as the main url to load.\n\t *\n\t * Can be set to different values in different test environments.\n\t *\n\t * @alias `baseUrl`, `base_url`, `launchUrl`, `launch_url` in order of precedence.\n\t */\n\tbaseUrl?: string;\n\n\t/**\n\t * A url which can be used later in the tests as the main url to load.\n\t *\n\t * Can be set to different values in different test environments.\n\t *\n\t * @alias `baseUrl`, `base_url`, `launchUrl`, `launch_url` in order of precedence.\n\t */\n\tbase_url?: string;\n\n\t/**\n\t * A url which can be used later in the tests as the main url to load.\n\t *\n\t * Can be set to different values in different test environments.\n\t *\n\t * @alias `baseUrl`, `base_url`, `launchUrl`, `launch_url` in order of precedence.\n\t */\n\tlaunchUrl?: string;\n\n\t/**\n\t * A url which can be used later in the tests as the main url to load.\n\t *\n\t * Can be set to different values in different test environments.\n\t *\n\t * @alias `baseUrl`, `base_url`, `launchUrl`, `launch_url` in order of precedence.\n\t */\n\tlaunch_url?: string;\n\n\t/**\n\t * The hostname/IP on which the selenium server is accepting connections.\n\t *\n\t * @deprecated In favour of `selenium.host`.\n\t */\n\tselenium_host?: string;\n\n\t/**\n\t * The port number on which the selenium server is accepting connections.\n\t *\n\t * @deprecated In favour of `selenium.port`.\n\t */\n\tselenium_port?: number;\n\n\t/**\n\t * An array of folders (excluding subfolders) where the tests are located.\n\t */\n\tsrc_folders?: string | string[] | null;\n\n\t/**\n\t * An object which will be passed to the Selenium WebDriver when a new session will be created. You can specify browser name for instance along with other capabilities.\n\t * Example:\n\t *  \"desiredCapabilities\" : {\n\t *  \"browserName\" : \"firefox\",\n\t *  \"acceptSslCerts\" : true\n\t * }\n\t * You can view the complete list of capabilities https://code.google.com/p/selenium/wiki/DesiredCapabilities.\n\t */\n\tdesiredCapabilities?: NightwatchDesiredCapabilities;\n\n\t/**\n\t * An object containing Selenium Server related configuration options. If Selenium Server is not used, webdriver options should be set instead.\n\t *\n\t * Starting with Nightwatch 1.0, Selenium is only required when testing against a Grid setup or a cloud testing service (such as SauceLabs or BrowserStack).\n\t */\n\tselenium?: NightwatchSeleniumOptions;\n\n\t/**\n\t * An object containing WebDriver related configuration options.\n\t */\n\twebdriver?: WebdriverOptions;\n\n\t/**\n\t * Specifies which test runner to use when running the tests. Set to 'default' to use built-in nightwatch runner.\n\t *\n\t * @example\n\t * \"test_runner\": {\"type\": \"mocha\", \"options\": {\"ui\": \"tdd\"}}\n\t *\n\t * @default 'default'\n\t */\n\ttest_runner?: string | NightwatchTestRunner;\n\n\t/**\n\t * Whether or not to run individual test files in parallel.\n\t *\n\t * If set to `true`, runs the tests in parallel and determines the number of workers automatically.\n\t *\n\t * If set to an object, can specify specify the number of workers as \"auto\" or a number.\n\t *\n\t * @example\n\t * \"test_workers\": {\"enabled\": true, \"workers\": \"auto\"}\n\t *\n\t * @default false\n\t */\n\ttest_workers?: boolean | NightwatchTestWorker;\n\n\t/**\n\t * Specifies which implementation to use for concurrency, child-process or worker-threads.\n\t */\n\tuse_child_process?: boolean;\n\n\t/**\n\t * Used when running in parallel to specify the delay (in milliseconds) between starting the child processes.\n\t * @default 10\n\t */\n\tparallel_process_delay?: number;\n\n\t/**\n\t * Enable aborting the test run execution when the first test failure occurs; the remaining test suites will be skipped.\n\t * @default false\n\t */\n\tenable_fail_fast?: boolean;\n\n\t/**\n\t * An object which will be made available within the test and can be overwritten per environment.\n\t *\n\t * @example\n\t * \"globals\": {\"myGlobal\": \"some_global\"}\n\t */\n\tglobals?: NightwatchGlobals;\n\n\t/**\n\t * Set this to `true` if you'd like to persist the same globals object between testsuite runs or have a (deep) copy of it per each testsuite.\n\t *\n\t * This can be useful when persisting data between test suites is needed, such as a cookie or session information.\n\t * @default false\n\t */\n\tpersist_globals?: boolean;\n\n\t/**\n\t * Whether or not to automatically start the Selenium/WebDriver session. If running unit tests, this should be set to false.\n\t * @default true\n\t */\n\tstart_session?: boolean;\n\n\t/**\n\t * End the session automatically when the test is being terminated, usually after a failed assertion.\n\t * @default true\n\t */\n\tend_session_on_fail?: boolean;\n\n\t/**\n\t * Skip the remaining test cases from the current test suite, when one test case fails.\n\t * @default true\n\t */\n\tskip_testcases_on_fail?: boolean;\n\n\t/**\n\t * Use xpath as the default locator strategy.\n\t * @default false\n\t */\n\tuse_xpath?: boolean;\n\n\t/**\n\t * Should be set to true if connecting to a remote (cloud) service via HTTPS. Also don't forget to set port to 443.\n\t * @deprecated In favour of `selenium.ssl`.\n\t * @default false\n\t */\n\tuse_ssl?: boolean;\n\n\t/**\n\t * A name property will be added to the `desiredCapabilities` containing the test suite name when this is enabled. It is useful when using cloud testing services.\n\t */\n\tsync_test_names?: boolean;\n\n\t/**\n\t * Selenium generates screenshots when command errors occur.\n\t *\n\t * With on_failure set to true, also generates screenshots for failing or erroring tests. These are saved on the disk.\n\t *\n\t * Since v0.7.5 you can disable screenshots for command errors by setting \"on_error\" to false.\n\t *\n\t * @example\n\t * \"screenshots\": {\n\t *      \"enabled\": true,\n\t *      \"on_failure\": true,\n\t *      \"on_error\": false,\n\t *      \"path\": \"\"\n\t * }\n\t */\n\tscreenshots?: NightwatchScreenshotOptions;\n\n\t/**\n\t * Controls whether to run tests in unit testing mode, which means the session will not automatically be created.=\n\t */\n\tunit_testing_mode?: boolean;\n\n\t/**\n\t * Controls whether to run tests in unit testing mode, which means the session will not automatically be created.\n\t * @deprecated In favour of `unit_testing_mode`.\n\t */\n\tunit_tests_mode?: boolean;\n\n\t/**\n\t * An array of folders or file patterns to be skipped (relative to the main source folder).\n\t *\n\t * @example\n\t * \"exclude\" : [\"excluded-folder\"]\n\t * or:\n\t * \"exclude\" : [\"test-folder/*-smoke.js\"]\n\t */\n\texclude?: string[] | null;\n\n\t/**\n\t * Folder or file pattern to be used when loading the tests. Files that don't match this pattern will be ignored.\n\t *\n\t * @example\n\t * \"filter\": \"tests/*-smoke.js\"\n\t */\n\tfilter?: string | null;\n\n\t/**\n\t * Skip a group of tests (a subfolder); can be a list of comma-separated values (no space).\n\t */\n\tskipgroup?: string;\n\n\t/**\n\t * Skip tests by tag name; can be a list of comma-separated values (no space).\n\t */\n\tskiptags?: string;\n\n\t/**\n\t * Tag(s) used/to be used during test execution.\n\t * Can be a single tag or an array of tags.\n\t */\n\ttag_filter?: string | string[];\n\n\t/**\n\t * Whether to show the extended HTTP traffic command logs from the WebDriver or Selenium server.\n\t *\n\t * @default true (do not show the extended command logs)\n\t */\n\tsilent?: boolean;\n\n\t/**\n\t * Used to disable terminal output completely.\n\t *\n\t * @default true\n\t */\n\toutput?: boolean;\n\n\t/**\n\t * By default detailed assertion output is displayed while the test is running.\n\t *\n\t * Set this to false if you'd like to only see the test case name displayed and pass/fail status.\n\t *\n\t * Detailed output is disabled by default when running tests in parallel.\n\t */\n\tdetailed_output?: boolean;\n\n\t/**\n\t * Set this to true if you'd like to see timestamps next to the logging output.\n\t */\n\toutput_timestamp?: boolean;\n\n\t/**\n\t * The location where the JUnit XML and HTML report files will be saved. Set this to false if you want to disable XML/HTML reporting.\n\t *\n\t * @default 'tests_output'\n\t */\n\toutput_folder?: string;\n\n\t/**\n\t * Settings for generated reports.\n\t */\n\treporter_options?: {\n\t\t/**\n\t\t * The location where the JUnit XML and HTML report files will be saved. Set this to false if you want to disable XML/HTML reporting.\n\t\t *\n\t\t * @default 'tests_output'\n\t\t */\n\t\toutput_folder?: string,\n\n\t\t/**\n\t\t * The name of the parent folder to save the HTML report in.\n\t\t * \n\t\t * This can be used to retain the HTML reports for all the test runs, by making the `folder_format` dynamic.\n\t\t * \n\t\t * @example\n\t\t * folder_format: () => Date.now().toString()\n\t\t */\n\t\tfolder_format?: string | (() => string) | null,\n\n\t\t/**\n\t\t * File name to use while saving the HTML report.\n\t\t *\n\t\t * Can be made dynamic by passing a function. Ex. `filename_format: () => Date.now().toString()`\n\t\t *\n\t\t * @default `index.html`\n\t\t */\n\t\tfilename_format?: string | (() => string) | null,\n\n\t\t/**\n\t\t * The location where the minimal JSON report should be saved.\n\t\t * This report is used by Nightwatch for its re-run functionality (re-running failed tests from previous run).\n\t\t *\n\t\t * @default 'tests_output/minimal_report.json'\n\t\t */\n\t\tminimal_report_file_path?: string;\n\t},\n\n\t/**\n\t * Use to disable colored output in the terminal.\n\t */\n\tdisable_colors?: boolean;\n\n\t/**\n\t * Set this to true if you'd like to disable bounding boxes on terminal output. Useful when running in some CI environments.\n\t */\n\tdisable_output_boxes?: boolean,\n\n\t/**\n\t * Used when running tests in parallel to determine if the output should be collected and displayed at the end.\n\t *\n\t * @default false\n\t */\n\tlive_output?: boolean;\n\n\t/**\n\t * Set this to 'iso' if you'd like to see timestamps as ISO strings.\n\t */\n\ttimestamp_format?: string,\n\n\t/**\n\t * Set this to true if you'd like to not display errors during the execution of the test (they are shown at the end always).\n\t *\n\t * @default false\n\t */\n\tdisable_error_log?: boolean;\n\n\t/**\n\t * Whether or not to show the Base64 image data in the (verbose) log when taking screenshots.\n\t *\n\t * @default false\n\t */\n\tlog_screenshot_data?: boolean;\n\n\t/**\n\t * Sets the initial window size: {height: number, width: number}\n\t */\n\twindow_size?: {\n\t\theight: number;\n\t\twidth: number;\n\t};\n}\n\nexport interface NightwatchOptions extends NightwatchTestSettingGeneric {\n\t/**\n\t * Location(s) where custom commands will be loaded from.\n\t */\n\tcustom_commands_path?: string | string[] | null;\n\n\t/**\n\t * Location(s) where custom assertions will be loaded from.\n\t */\n\tcustom_assertions_path?: string | string[] | null;\n\n\t/**\n\t * Location(s) where page object files will be loaded from.\n\t */\n\tpage_objects_path?: string | string[] | null;\n\n\t/**\n\t * An array specifying a list of Nightwatch plugin names that should be used.\n\t *\n\t * @example\n\t * plugins: ['@nightwatch/react']\n\t */\n\tplugins?: string[];\n\n\t/**\n\t * Location of the tsconfig file to be used by Nightwatch for running tests written in TS.\n\t * @default 'nightwatch/tsconfig.json'\n\t */\n\ttsconfig_path?: string;\n\n\t/**\n\t * Location of an external globals module which will be loaded and made available to the test as a property globals on the main client instance.\n\t * Globals can also be defined/overwritten inside a test_settings environment.\n\t */\n\tglobals_path?: string | null;\n\n\t/**\n\t * configuration settings for the dotenv module - a zero-dependency module that loads environment variables from a .env file into process.env. More details on https://www.npmjs.com/package/dotenv\n\t */\n\tdotenv?: any;\n\n\t/**\n\t * Disable support for loading of typescript test files for backwards compatibility with test suites.\n\t */\n\tdisable_typescript?: boolean;\n\n\t/**\n\t * This object contains all the test related options. See below for details.\n\t */\n\ttest_settings: NightwatchTestSettings;\n\n\tparallel_mode?: boolean;\n\n\treport_prefix?: string;\n\n\t/**\n\t * @default junit\n\t */\n\tdefault_reporter?: string | string[];\n\n\t/**\n\t * Set this to true to use the v1.x response format for commands in v2.x when using ES6 async/await.\n\t * Can also be used to retain the older functionality of `browser.element()` in v3.x.\n\t * \n\t * @default false\n\t */\n\tbackwards_compatibility_mode?: boolean;\n\n\t/**\n\t * Set this to true to disable the global objects such as element(), browser, by(), expect()\n\t */\n\tdisable_global_apis?: boolean;\n\n\t/**\n\t * Disable the globally available expect() api.\n\t */\n\tdisable_global_expect?: boolean;\n\n\t/**\n\t * Whether or not to report API command errors that don't deal with DOM elements (e.g. cookie).\n\t * @default false\n\t */\n\treport_command_errors?: boolean,\n\n\t/**\n\t * Whether or not to report network errors (e.g. ECONNRESET errors)\n\t * @default true\n\t */\n\treport_network_errors?: boolean;\n\n\t/**\n\t * Interactive element commands such as \"click\" or \"setValue\" can be retried\n\t * if an error occurred (such as an \"element not interactable\" error)\n\t */\n\telement_command_retries?: number;\n\n\t/**\n\t * Settings related to tracing [DOM History](https://nightwatchjs.org/guide/reporters/dom-history.html#enable-dom-history).\n\t */\n\ttrace?: {\n\t\tenabled: boolean;\n\t\tpath?: string;\n\t\tfilename_format?: (failureData: {\n\t\t\ttestSuite: string;\n\t\t\ttestCase: string;\n\t\t\tisError: boolean;\n\t\t\tdateObject: Date;\n\t\t}) => string;\n\t}\n\n\t/**\n\t * Whether or not to consider all commands as being running in async mode.\n\t *\n\t * Setting this to true will result in all commands returning a promise, even when they are used in non-async tests.\n\t */\n\talways_async_commands?: boolean;\n\n\t/**\n\t * Settings for anonymous usage metrics collection.\n\t */\n\tusage_analytics?: {\n\t\tenabled: boolean;\n\t\t/**\n\t\t * @default './logs/analytics'\n\t\t */\n\t\tlog_path?: string;\n\t\tclient_id?: string;\n\t}\n}\n\nexport interface TimeoutOptions {\n\t/**\n\t * @default 90000\n\t */\n\ttimeout: number;\n\n\t/**\n\t * @default 2\n\t */\n\tretry_attempts: number;\n}  \n\nexport interface WebdriverOptions {\n\t/**\n\t * When this is enabled, the Webdriver server is run in background in a child process and started/stopped automatically.\n\t *\n\t * Nightwatch includes support for managing Chromedriver, Geckodriver (Firefox), Safaridriver, and Selenium Server.\n\t *\n\t * @default false\n\t */\n\tstart_process?: boolean;\n\n\t/**\n\t * Absolute path to the webdriver binary. Only useful if start_process is enabled.\n\t * @default none\n\t */\n\tserver_path?: string | null;\n\n\t/**\n\t * Only needed when the Webdriver service is running on a different machine.\n\t */\n\thost?: string;\n\n\t/**\n\t * The port number on which the Webdriver service will listen and/or on which Nightwatch will attempt to connect.\n\t */\n\tport?: number;\n\n\t/**\n\t * Should be set to true if connecting to a remote (cloud) service via HTTPS. Also don't forget to set port to 443.\n\t */\n\tssl?: boolean;\n\n\t/**\n\t * The location where the Webdriver service log file output.log file will be placed. Defaults to current directory.\n\t *\n\t * To disable Webdriver logging, set this to false.\n\t * @default none\n\t */\n\tlog_path?: string | boolean;\n\n\t/**\n\t * File name to use when writing the webdriver server logs.\n\t *\n\t * By default, the log file name will be the same as the testsuite file name.\n\t */\n\tlog_file_name?: string;\n\n\t/**\n\t * List of cli arguments to be passed to the Webdriver process. This varies for each Webdriver implementation.\n\t *\n\t * @default none\n\t */\n\tcli_args?: string[] | {};\n\n\t/**\n\t * Some Webdriver implementations (Safari, Edge) support both the W3C Webdriver API as well as the legacy JSON Wire (Selenium) API.\n\t *\n\t * @default false\n\t */\n\tuse_legacy_jsonwire?: boolean;\n\n\t/**\n\t * Time to wait (in ms) before starting to check the Webdriver server is up and running.\n\t *\n\t * @default 100\n\t */\n\tcheck_process_delay?: number;\n\n\t/**\n\t * Enable HTTP Keep-Alive.\n\t *\n\t * If set to true, the keepAlive option is enabled with default settings (`keepAliveMsecs` = 3000).\n\t *\n\t * If set to an object, you can specify specify the `keepAliveMsecs` value.\n\t *\n\t * @example\n\t * \"keep_alive\": {\"enabled\": true, \"keepAliveMsecs\": 2000}\n\t */\n\tkeep_alive?: boolean | {\n\t\tenabled: boolean,\n\t\tkeepAliveMsecs: number\n\t};\n\n\t/**\n\t * Requests to the Webdriver service will timeout in `timeout` milliseconds; a retry will happen `retry_attempts` number of times.\n\t *\n\t * @example {timeout: 15000, retry_attempts: 5}\n\t */\n\ttimeout_options?: TimeoutOptions;\n\n\t/**\n\t * Interval (in ms) to use between status ping checks when checking if the Webdriver server is up and running.\n\t *\n\t * @default 100\n\t */\n\tstatus_poll_interval?: number;\n\n\t/**\n\t * Maximum number of ping status check attempts when checking if the Webdriver server is up and running before returning a timeout error.\n\t *\n\t * @default 5\n\t */\n\tmax_status_poll_tries?: number;\n\n\t/**\n\t * The entire time (in ms) to wait for the Node.js process to be created and running (default is 2 min), including spawning the child process and checking the status.\n\t *\n\t * @default 120000\n\t */\n\tprocess_create_timeout?: number;\n\n\t/**\n\t * Interval (in ms) to wait for before sending another request to the WebDriver server in case of an Internal Server Error (5xx).\n\t *\n\t * Number of times the retry attempts are made depend on `timeout_options.retryAttempts` webdriver setting.\n\t */\n\tinternal_server_error_retry_interval?: number;\n\n\t/**\n\t * Usually only needed for cloud testing Selenium services. In case the server requires credentials this username will be used to compute the `Authorization` header.\n\t *\n\t * The value can be also an environment variable, in which case it will look like this:\n\t * `\"username\": \"${SAUCE_USERNAME}\"`\n\t *\n\t * @default none\n\t */\n\tusername?: string;\n\n\t/**\n\t * This field will be used together with `username` to compute the `Authorization` header.\n\t *\n\t * Like `username`, the value can be also an environment variable:\n\t * `\"access_key\": \"${SAUCE_ACCESS_KEY}\"`\n\t *\n\t * @default none\n\t */\n\taccess_key?: string;\n\n\t/**\n\t * Proxy requests to the Webdriver (or Selenium) service. http, https, socks(v5), socks5, sock4, and pac are accepted. Uses node-proxy-agent.\n\t *\n\t * @example http://user:pass@host:port\n\t * @default none\n\t */\n\tproxy?: string;\n\n\t/**\n\t * Needed sometimes when using a Selenium Server. The prefix to be added to to all requests (e.g. `/wd/hub`).\n\t */\n\tdefault_path_prefix?: string;\n\n\t/**\n\t * Sets the path to the Chrome binary to use.\n\t * On Mac OS X, this path should reference the actual Chrome executable,\n\t * not just the application binary (e.g. \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\").\n\t */\n\tchrome_binary?: string;\n\n\t/**\n\t * Sets the path to Chrome's log file. This path should exist on the machine that will launch Chrome.\n\t */\n\tchrome_log_file?: string;\n\n\t/**\n\t * Configures the ChromeDriver to launch Chrome on Android via adb.\n\t */\n\tandroid_chrome?: false;\n\n\t/**\n\t * Sets the path to the Edge binary to use. This path should exist on the machine that will launch Edge.\n\t */\n\tedge_binary?: '';\n\n\t/**\n\t * Sets the path to the Edge binary to use.\n\t */\n\tedge_log_file?: '';\n\n\t/**\n\t * Sets the binary to use. The binary may be specified as the path to a Firefox executable or a desired release Channel. This path should exist on the machine that will launch Firefox.\n\t */\n\tfirefox_binary?: '';\n\n\t/**\n\t * Sets the path to an existing profile to use as a template for new browser sessions.\n\t * This profile will be copied for each new session - changes will not be applied to the profile itself.\n\t */\n\tfirefox_profile?: '';\n}\n\nexport interface NightwatchSeleniumOptions {\n\t/**\n\t * Whether or not to manage the selenium process automatically.\n\t * @default false\n\t */\n\tstart_process?: boolean;\n\n\t/**\n\t * Whether or not to automatically start the Selenium session.\n\t */\n\tstart_session?: boolean;\n\n\t/**\n\t * The location of the selenium jar file. Leave empty if @nightwatch/selenium-server is installed.\n\t *\n\t * @example 'lib/selenium-server-standalone-2.43.0.jar'\n\t */\n\tserver_path?: string | null;\n\n\t/**\n\t * Required when using Selenium 4. Set this to 'standalone'.\n\t */\n\tcommand?: string;\n\n\t/**\n\t * The location where the selenium Selenium `output.log` file will be placed. Defaults to current directory.\n\t *\n\t * To disable Selenium logging, set this to `false`.\n\t */\n\tlog_path?: string | boolean;\n\n\t/**\n\t * The IP address Selenium will listen on and/or Nightwatch will attempt to connect to.\n\t */\n\thost?: string;\n\n\t/**\n\t * The port number Selenium will listen on and/or Nightwatch will attempt to connect to.\n\t */\n\tport?: number;\n\n\t/**\n\t * List of cli arguments to be passed to the Selenium process. Here you can set various options for browser drivers, such as:\n\t *\n\t * `webdriver.firefox.profile`: Selenium will be default create a new Firefox profile for each session.\n\t * If you wish to use an existing Firefox profile you can specify its name here.\n\t * Complete list of Firefox Driver arguments available https://code.google.com/p/selenium/wiki/FirefoxDriver.\n\t *\n\t * `webdriver.chrome.driver`: Nightwatch can run the tests using Chrome browser also. To enable this you have to download the ChromeDriver binary\n\t * (http://chromedriver.storage.googleapis.com/index.html) and specify it's location here. Also don't forget to specify chrome as the browser name in the\n\t * desiredCapabilities object.\n\t * More information can be found on the ChromeDriver website (https://sites.google.com/a/chromium.org/chromedriver/).\n\t *\n\t * `webdriver.ie.driver`: Nightwatch has support for Internet Explorer also. To enable this you have to download the IE Driver binary\n\t * (https://code.google.com/p/selenium/wiki/InternetExplorerDriver) and specify it's location here. Also don't forget to specify \"internet explorer\" as the browser\n\t * name in the desiredCapabilities object.\n\t */\n\tcli_args?: {};\n\n\t/**\n\t * Set this to true when using Nightwatch to manage and/or connect to an Appium server.\n\t */\n\tuse_appium?: boolean;\n\n\t/**\n\t * Time to wait (in ms) before starting to check the Selenium server is up and running\n\t * @default 500\n\t */\n\tcheck_process_delay?: number;\n\n\t/**\n\t * Maximum number of ping status check attempts before returning a timeout error.\n\t * @default 15\n\t */\n\tmax_status_poll_tries?: number;\n\n\t/**\n\t * Interval (in ms) to use between status ping checks when checking if the Selenium server is up and running.\n\t * @default 200\n\t */\n\tstatus_poll_interval?: number;\n}\n\nexport interface NightwatchTestOptions extends NightwatchTestSettingGeneric {\n\t/**\n\t * Path where screenshots captured during test failure or error will be saved.\n\t */\n\tscreenshotsPath: string;\n\n\t/**\n\t * In case the selenium server requires credentials this username will be used to compute the Authorization header.\n\t */\n\tusername?: string;\n\n\t/**\n\t * This field will be used together with username to compute the Authorization header.\n\t */\n\taccessKey?: string;\n}\n\nexport interface NightwatchTestSettings {\n\t[key: string]: NightwatchTestSettingGeneric & {\n\t\t/**\n\t\t * Inherit settings from another environment.\n\t\t */\n\t\textends?: string;\n\t};\n}\n"
  },
  {
    "path": "types/page-object.d.ts",
    "content": "import {MergeObjectsArray} from './utils';\nimport {NightwatchCustomCommands} from './custom-command';\nimport {\n  AlertsNsCommands,\n  Assert,\n  ChromiumClientCommands,\n  CookiesNsCommands,\n  DocumentNsCommands,\n  ElementCommands,\n  ElementFunction,\n  Expect,\n  KeysFilter,\n  LocateStrategy,\n  NightwatchAPI,\n  NightwatchClient,\n  NightwatchComponentTestingCommands,\n  SharedClientCommands\n} from './index';\n\nexport interface PageObjectClientCommands\n  extends ChromiumClientCommands,\n    SharedClientCommands {}\n\nexport interface SectionProperties {\n  /**\n   * The selector string to be used to find the section in the DOM.\n   *\n   * @example\n   * sections: {\n   *   apps: {\n   *     selector: 'div.gb_pc'\n   *   }\n   * }\n   */\n  selector: string;\n\n  /**\n   * The locate strategy to be used with `selector` when finding the section within the DOM.\n   *  - css selector\n   *  - link text\n   *  - partial link text\n   *  - tag name\n   *  - xpath\n   *\n   * @example\n   * 'css selector'\n   */\n  locateStrategy?: LocateStrategy;\n\n  /**\n   * An object, or array of objects, of named element definitions to be used\n   * as element selectors within element commands.\n   *\n   * @example\n   * sections: {\n   *   apps: {\n   *     selector: 'div.gb_pc',\n   *     elements: {\n   *       myAccount: {\n   *         selector: '#gb192'\n   *       },\n   *       googlePlus: {\n   *         selector: '#gb119'\n   *       }\n   *     }\n   *   }\n   * }\n   */\n  elements?:\n  | Partial<{ [name: string]: string | ElementProperties }>\n  | Partial<{ [name: string]: string | ElementProperties }>[];\n\n  /**\n   * An object of named sections definitions defining the sections.\n   *\n   * @example\n   * sections: {\n   *   menu: {\n   *     selector: '#gb',\n   *     sections: {\n   *       apps: {\n   *         selector: 'div.gb_pc',\n   *         elements: {\n   *           myAccount: {\n   *             selector: '#gb192'\n   *           }\n   *         }\n   *       }\n   *     }\n   *   }\n   * }\n   */\n  sections?: {\n    [name: string]: SectionProperties;\n  };\n\n  /**\n   * A list of objects containing functions to represent methods added to the section.\n   *\n   * @example\n   * sections: {\n   *   apps: {\n   *     selector: 'div.gb_pc',\n   *     commands: [\n   *       {\n   *         clickYoutube() {\n   *           console.log('Click Youtube')\n   *         }\n   *       }\n   *     ]\n   *   }\n   * }\n   */\n  commands?:\n    | Partial<Record<string, (...args: any) => unknown>>\n    | Partial<Record<string, (...args: any) => unknown>>[];\n\n  /**\n   * An object or a function returning an object representing a container for user variables.\n   * Props objects are copied directly into the props property of the page object instance.\n   *\n   * @example\n   * sections: {\n   *   apps: {\n   *     selector: 'div.gb_pc',\n   *     // object version\n   *     props: {\n   *       myVar: \"some info\"\n   *     }\n   *   },\n   *   menu: {\n   *     selector: '#gb',\n   *     // function version\n   *     props: function () {\n   *       return {\n   *         myOtherVar: \"some other info\"\n   *       };\n   *     }\n   *   }\n   * }\n   */\n  props?: Record<string, unknown> | (() => Record<string, unknown>);\n}\n\nexport type EnhancedSectionInstance<\n  Commands = {},\n  Elements = {},\n  Sections extends Record<string, PageObjectSection> = {},\n  Props = {},\n  Parent = unknown\n> = EnhancedPageObjectSections<Commands, Elements, Sections, Props, Parent> &\n  Commands &\n  ElementCommands &\n  PageObjectClientCommands &\n  Pick<NightwatchCustomCommands, KeysFilter<NightwatchCustomCommands, Function>> & // eslint-disable-line @typescript-eslint/ban-types\n  Pick<\n    NightwatchComponentTestingCommands,\n    'importScript' | 'launchComponentRenderer' | 'mountComponent'\n  >;\n\ninterface PageObjectSection {\n  commands?: Record<string, unknown> | Record<string, unknown>[];\n  elements?: Record<string, unknown> | Record<string, unknown>[];\n  props?: Record<string, unknown>;\n  // TODO: make sections type more strict.\n  sections?: any;\n}\n\nexport interface EnhancedPageObjectSections<\n  Commands = {},\n  Elements = {},\n  Sections extends Record<string, PageObjectSection> = {},\n  Props = {},\n  Parent = unknown\n> extends EnhancedPageObjectSharedFields<\n  Commands,\n  Elements,\n  Sections,\n  Props\n> {\n  /**\n   * The selector string used to find the section in the DOM.\n   *\n   * @example\n   * '#searchBar'\n   */\n  selector: string;\n\n  /**\n   * The locate strategy used with `selector` when finding the section within the DOM.\n   *  - css selector\n   *  - link text\n   *  - partial link text\n   *  - tag name\n   *  - xpath\n   *\n   * @example\n   * 'css selector'\n   */\n  locateStrategy: LocateStrategy;\n\n  /**\n   * Parent of the section.\n   */\n  parent: Parent;\n}\n\ninterface EnhancedPageObjectSharedFields<\n  Commands = {},\n  Elements = {},\n  Sections extends Record<string, PageObjectSection> = {},\n  Props = {},\n  URL = string\n> {\n  /**\n   * A map of Element objects\n   * (see [Enhanced Element Instances](https://github.com/nightwatchjs/nightwatch/wiki/Page-Object-API#enhanced-element-instances))\n   * used by element selectors.\n   */\n  elements: {\n    [key in keyof Elements]: EnhancedElementInstance<\n      EnhancedPageObject<Commands, Elements, Sections, Props, URL>\n    >;\n  };\n\n  /**\n   * Section object\n   * (see [Enhanced Element Instances](https://github.com/nightwatchjs/nightwatch/wiki/Page-Object-API#enhanced-section-instances))\n   */\n  section: {\n    [Key in keyof Sections]: EnhancedSectionInstance<\n      Required<MergeObjectsArray<Sections[Key]['commands']>>,\n      Required<MergeObjectsArray<Sections[Key]['elements']>>,\n      Required<Sections[Key]['sections']>,\n      Required<Sections[Key]['props']>,\n      this\n    >;\n  };\n\n  /**\n   * The name of the page object as defined by its module name (not including the extension).\n   * This is the same name used to access the `page` object factory from the page reference in the command API.\n   */\n  name: string;\n\n  /**\n   * An object or a function returning an object representing a container for user variables.\n   */\n  props: Props;\n\n  /**\n   * Nightwatch Client.\n   */ \n  client: NightwatchClient;\n\n  /**\n   * Nightwatch API.\n   */\n  api: NightwatchAPI;\n\n  /**\n   * Nightwatch new element API.\n   */\n  element: ElementFunction;\n\n  // Namespaces directly available on page-objects and sections.\n  alerts: AlertsNsCommands<this>;\n  cookies: CookiesNsCommands<this>;\n  document: DocumentNsCommands<this>;\n  assert: Assert<this>;\n  verify: Assert<this>;\n  expect: Expect;\n}\n\nexport interface ElementProperties {\n  /**\n   * The selector string to be used to find the element in the DOM.\n   *\n   * @example\n   * '#searchBar'\n   */\n  selector: string;\n\n  /**\n   * The locate strategy to be used with `selector` when finding the element within the DOM.\n   *  - css selector\n   *  - link text\n   *  - partial link text\n   *  - tag name\n   *  - xpath\n   *\n   * @example\n   * 'css selector'\n   */\n  locateStrategy?: LocateStrategy;\n\n  /**\n   * used to target a specific element in a query that results in multiple elements returned. Normally,\n   * only the first element is used (index = 0) but using the index property, you can specify any element within the result.\n   */\n  index?: number;\n\n  /**\n   * used to overwrite this setting when using waitForElement* commands.\n   */\n  abortOnFailure?: boolean;\n\n  /**\n   * used to overwrite the default timeout for when using waitForElement* commands or assertions.\n   */\n  timeout?: number;\n\n  /**\n   * used to overwrite the default retry interval for when using waitForElement* commands or assertions.\n   */\n  retryInterval?: number;\n\n  /**\n   * Some element commands like .click() or .getText() will throw a NoSuchElement error if the element cannot be located, causing the test to fail.\n   * If this option is set to true then this error is ignored.\n   */\n  suppressNotFoundErrors?: boolean;\n}\n\n/**\n * #### [Enhanced Element Instances](https://github.com/nightwatchjs/nightwatch/wiki/Page-Object-API#enhanced-element-instances)\n * Element instances encapsulate the definition used to handle element selectors.\n * Generally you won't need to access them directly,\n * instead referring to them using their `@`-prefixed names for selector arguments,\n * but they are available through a page object or section's elements property.\n */\nexport interface EnhancedElementInstance<T> {\n  /**\n   * The name of the element as defined by its key in the parent section or the page object's `elements` definition.\n   * This is the same name used with the `@` prefix in selector arguments for page object commands that refer to the element.\n   */\n  name: string;\n\n  /**\n   * The locate strategy to be used with `selector` when finding the element within the DOM.\n   */\n  locateStrategy: LocateStrategy;\n\n  /**\n   * A reference to the parent object instance.\n   * This is the parent section or the page object that contained the definition for this object.\n   */\n  parent: T;\n\n  /**\n   * The selector string used to find the element in the DOM.\n   */\n  selector: string;\n}\n\n/**\n * Page objects provide an additional layer of abstraction for test case creation.\n * Page objects are defined in modules and parsed into factory functions that create page object instances.\n *\n * @see https://nightwatchjs.org/api/pageobject/#overview\n *\n * @remarks Use satisfies to preserve types!\n *\n * @example\n * const homePage = {\n *   // Some options\n * } satisfies PageObjectModel;\n */\n\nexport interface PageObjectModel {\n  /**\n   * A list of objects containing functions to represent methods added to the page object instance.\n   * Page-specific commands: {@link https://nightwatchjs.org/guide/using-page-objects/writing-page-specific-commands.html}\n   *\n   * @example\n   * class MyCommands {\n   *   myFirstMethod() {\n   *     return 'My First Method';\n   *   }\n   * }\n   *\n   * const homePage = {\n   *   commands: MyCommands\n   * } satisfies PageObjectModel;\n   */\n  commands?:\n    | Partial<Record<string, (...args: any) => unknown>>\n    | Partial<Record<string, (...args: any) => unknown>>[];\n\n  /**\n   * An object, or array of objects, of named element definitions to be used\n   * as element selectors within element commands called from the page object.\n   *\n   * @example\n   * const homePage = {\n   *   elements: [\n   *     {\n   *       contactUs: \"#contactUs\",\n   *       searchBar: {\n   *         selector: 'input[type=text]',\n   *       },\n   *       submitButton: {\n   *         selector: 'input[name=btnK]',\n   *       },\n   *     },\n   *   ]\n   * } satisfies PageObjectModel;\n   */\n  elements?:\n  | Partial<{ [name: string]: string | ElementProperties }>\n  | Partial<{ [name: string]: string | ElementProperties }>[];\n\n  /**\n   * An object or a function returning an object representing a container for user variables.\n   * Props objects are copied directly into the props property of the page object instance.\n   *\n   * @example\n   * const homePage = {\n   *   props: {\n   *     myVar: \"some info\"\n   *   }\n   * } satisfies PageObjectModel;\n   */\n  props?: Record<string, unknown> | (() => Record<string, unknown>);\n\n  /**\n   * An object of named sections definitions defining the sections within the page object.\n   *\n   * @example\n   * const homePage = {\n   *   sections: {\n   *     menu: {\n   *       selector: '#gb',\n   *       elements: {\n   *         mail: {\n   *           selector: 'a[href=\"https://mail.google.com/mail/&ogbl\"]'\n   *         }\n   *       }\n   *     }\n   *   }\n   * } satisfies PageObjectModel;\n   */\n  sections?: {\n    [name: string]: SectionProperties;\n  };\n\n  /**\n   * A url or function returning a url to be used in a url() command when the page's navigate() method is called.\n   *\n   * @example\n   * const homePage = {\n   *   url: function() {\n   *      return this.api.launchUrl;\n   *   }\n   * } satisfies PageObjectModel;\n   */\n  url?: string | ((...args: any) => string);\n}\n\n/**\n * #### [Enhanced Page Object Instances](https://github.com/nightwatchjs/nightwatch/wiki/Page-Object-API#enhanced-page-object-instances)\n * Page object module definitions are used to define page object instances when their respective\n * factory functions within the page reference of the standard command API is called.\n * ```\n * const myPageObject = browser.page.MyPage(); // defined in MyPage.js module\n * ```\n * Every time a factory function like MyPage above is called, a new instance of the page object is instantiated.\n */\nexport type EnhancedPageObject<\n  Commands = {},\n  Elements = {},\n  Sections extends Record<string, PageObjectSection> = {},\n  Props = {},\n  URL = string\n> = PageObjectClientCommands &\n  ElementCommands &\n  NightwatchCustomCommands &\n  EnhancedPageObjectSharedFields<\n    Required<MergeObjectsArray<Commands>>,\n    Required<MergeObjectsArray<Elements>>,\n    Sections,\n    Props,\n    URL\n  > &\n  Required<MergeObjectsArray<Commands>> & {\n    /**\n     * A url or a function returning a url. This is also used internally when the page's navigate() method is called.\n     *\n     * By default, the url property is set to a string type. To set it to a function type instead, the fifth type parameter\n     * of the `EnhancedPageObject` interface can be used:\n     *\n     * ```\n     * export interface MyPage extends\n     *   EnhancedPageObject<{}, typeof elements, {}, {}, () => string> {}\n     * ```\n     *\n     * See the usage of the `EnhancedPageObject` interface\n     * [here](https://github.com/nightwatchjs-community/nightwatch-typescript-boilerplate/blob/0bf15a6e8735b576b82bce9a7bb5c6beddb14de4/nightwatch/pages/FileUpload.ts#L17)\n     * for reference.\n     *\n     * @example\n     * const homePageObject = browser.page.homePage();\n     *\n     * googlePage.url; // if string type\n     * googlePage.url(); // if function type\n     */\n    url: URL;\n\n    /**\n     * This command is an alias to url and also a convenience method because when called without any arguments\n     * it performs a call to .url() with passing the value of `url` property on the page object.\n     * Uses `url` protocol command.\n     *\n     * @example\n     * const homePageObject = browser.page.homePage();\n     *\n     * homePageObject.navigate();\n     */\n    navigate(\n      url?: string,\n      callback?: () => void\n    ): EnhancedPageObject<Commands, Elements, Sections, Props, URL>;\n  };\n"
  },
  {
    "path": "types/tests/actions.test-d.ts",
    "content": "import { expectError, expectType } from 'tsd';\nimport { Awaitable, NightwatchAPI } from '..';\nimport { WebElement } from 'selenium-webdriver';\n\n// Expect test for language chains\n\nit('actions.press', () => {\n  browser.perform(() => {\n    return browser.actions().press();\n  });\n});\n\nit('actions.release', () => {\n  browser.perform(() => {\n    return browser.actions().release();\n  });\n});\n\nit('actions.mouse', () => {\n  browser.perform(() => {\n    return browser.actions().mouse();\n  });\n});\n\nit('actions.keyboard', () => {\n  browser.perform(() => {\n    return browser.actions().keyboard();\n  });\n});\n\nit('actions.move', () => {\n  browser.perform(() => {\n    return browser.actions().move({ x: 100, y: 200 });\n  });\n});\n\nit('actions.clear', () => {\n  browser.perform(() => {\n    return browser.actions().clear();\n  });\n});\n\nit('actions.pause', () => {\n  browser.perform(() => {\n    return browser.actions().pause();\n  });\n});\n\nit('actions.dragAndDrop', () => {\n  browser.perform(async () => {\n    const sampleElement = element('.element-class');\n    const webElement = await sampleElement.getWebElement();\n    browser.actions().dragAndDrop(webElement, { x: 12, y: 234 });\n\n    const webElement2 = sampleElement.findElement();\n    expectType<Awaitable<NightwatchAPI, WebElement>>(webElement2);\n    expectError(browser.actions().dragAndDrop(webElement2, { x: 12, y: 234 }));\n    browser.actions().dragAndDrop(await webElement2, { x: 12, y: 234 });\n\n    const webElement3 = await sampleElement.findElement('something');\n    return browser.actions().dragAndDrop(webElement3, { x: 12, y: 234 });\n  });\n});\n\nit('actions.doubleClick', () => {\n  browser.perform(() => {\n    return browser.actions().doubleClick();\n  });\n});\n\nit('actions.contextClick', () => {\n  browser.perform(() => {\n    return browser.actions().contextClick();\n  });\n});\n\nit('actions.keyDown', () => {\n  browser.perform(() => {\n    return browser.actions().keyDown('CONTROL');\n  });\n});\n\nit('actions.keyUp', () => {\n  browser.perform(() => {\n    return browser.actions().keyUp('CONTROL');\n  });\n});\n\nit('actions.sendKeys', () => {\n  browser.perform(() => {\n    return browser.actions().sendKeys();\n  });\n});\n\nit('actions.perform', () => {\n  browser.perform(() => {\n    browser.actions().sendKeys().perform();\n  });\n});\n\nit('actions.options.async.bridge', () => {\n  browser.perform(() => {\n    return browser.actions({ async: true, bridge: true }).sendKeys();\n  });\n});\n\nit('actions.options.async', () => {\n  browser.perform(() => {\n    return browser.actions({ async: true }).sendKeys();\n  });\n});\n\nit('actions.options.bridge', () => {\n  browser.perform(() => {\n    return browser.actions({ bridge: true }).sendKeys();\n  });\n});\n"
  },
  {
    "path": "types/tests/appiumCommands.test-d.ts",
    "content": "import { expectError, expectType } from 'tsd';\nimport { AppiumGeolocation, NightwatchAPI } from '..';\n\n//\n// orientation\n//\ndescribe('orientation commands', function () {\n  it('tests orientation commands', function () {\n    expectType<NightwatchAPI>(app);\n    expectType<boolean>(app.isAppiumClient());\n\n    app.appium\n      .getOrientation(function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<'LANDSCAPE' | 'PORTRAIT'>(result.value);\n        }\n      })\n      .appium.setOrientation('LANDSCAPE', function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<'LANDSCAPE' | 'PORTRAIT'>(result.value);\n        }\n      });\n  });\n\n  it('tests orientation commands with async/await', async function () {\n    expectType<NightwatchAPI>(app);\n    expectType<boolean>(app.isAppiumClient());\n\n    const orientation = await app.appium.getOrientation();\n    expectType<'LANDSCAPE' | 'PORTRAIT'>(orientation);\n\n    const result = await app.appium.setOrientation('PORTRAIT');\n    expectType<'LANDSCAPE' | 'PORTRAIT'>(result);\n  });\n});\n\n//\n// context commands\n//\ndescribe('context commands', function () {\n  it('tests context commands', function (app: NightwatchAPI) {\n    expectType<boolean>(app.isAppiumClient());\n\n    app.appium\n      .getContexts(function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<string[]>(result.value);\n        }\n      })\n      .appium.getContext(function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<string | null>(result.value);\n        }\n      })\n      .appium.setContext('something', function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<null>(result.value);\n        }\n      });\n  });\n\n  it('tests context commands with async/await', async function (app: NightwatchAPI) {\n    expectType<boolean>(app.isAppiumClient());\n\n    const contexts = await app.appium.getContexts();\n    expectType<string[]>(contexts);\n\n    const context = await app.appium.getContext();\n    expectType<string | null>(context);\n\n    const result = await app.appium.setContext('random');\n    expectType<null>(result);\n  });\n});\n\n//\n// activity commands\n//\ndescribe('activity commands', function () {\n  it('tests activity commands', function (app: NightwatchAPI) {\n    app.appium\n      .startActivity(\n        {\n          appPackage: 'com.some.package',\n          appActivity: 'some.activity',\n        },\n        function (result) {\n          expectType<NightwatchAPI>(this);\n          if (result.status === 0) {\n            expectType<null>(result.value);\n          }\n        }\n      )\n      .appium.getCurrentActivity(function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<string>(result.value);\n        }\n      })\n      .appium.getCurrentPackage(function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<string>(result.value);\n        }\n      });\n  });\n\n  it('tests activity commands with async/await', async function (app: NightwatchAPI) {\n    expectError(await app.appium.startActivity({\n      appPackage: 'com.something',\n    }))\n\n    const result = await app.appium.startActivity({\n      appPackage: 'com.something',\n      appActivity: 'some.activity',\n      appWaitActivity: 'some.other.activity',\n    });\n    expectType<null>(result);\n\n    const activity = await app.appium.getCurrentActivity();\n    expectType<string>(activity);\n\n    const packageName = await app.appium.getCurrentPackage();\n    expectType<string>(packageName);\n  });\n});\n\n//\n// geolocation\n//\ndescribe('geolocation commands', function () {\n  it('tests geolocation commands', function (app: NightwatchAPI) {\n    app.appium\n      .getGeolocation(function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<AppiumGeolocation>(result.value);\n        }\n      })\n      .appium.setGeolocation({ latitude: 232, longitude: 2343, altitude: 5 }, function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<AppiumGeolocation>(result.value);\n        }\n      });\n  });\n\n  it('tests geolocation commands with async/await', async function (app: NightwatchAPI) {\n    const location = await app.appium.getGeolocation();\n    expectType<AppiumGeolocation>(location);\n    expectError(await app.appium.setGeolocation({ latitude: 543 }))\n    expectError(await app.appium.setGeolocation())\n\n    const result = await app.appium.setGeolocation({ latitude: 232, longitude: 2343 });\n    expectType<AppiumGeolocation>(result);\n  });\n});\n\n//\n// keyboard interaction commands\n//\ndescribe('keyboard interaction commands', function () {\n  it('tests keyboard interaction commands', function (app: NightwatchAPI) {\n    app.appium\n      .pressKeyCode(35, function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<null>(result.value);\n        }\n      })\n      .appium.longPressKeyCode(31, function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<null>(result.value);\n        }\n      })\n      .appium.hideKeyboard(function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<boolean>(result.value);\n        }\n      })\n      .appium.isKeyboardShown(function (result) {\n        expectType<NightwatchAPI>(this);\n        if (result.status === 0) {\n          expectType<boolean>(result.value);\n        }\n      });\n  });\n\n  it('tests keyboard interaction commands with async/await', async function (app: NightwatchAPI) {\n    expectError(await app.appium.pressKeyCode())\n    expectError(await app.appium.pressKeyCode(32, 45, () => {}))\n\n    await app.appium.pressKeyCode(56, () => {});\n    await app.appium.pressKeyCode(44, undefined, undefined, () => {});\n\n    const result = await app.appium.pressKeyCode(34, 29474, undefined, () => {});\n    expectType<null>(result);\n\n    expectError(await app.appium.longPressKeyCode())\n    expectError(await app.appium.longPressKeyCode(32, 45, () => {}))\n\n    await app.appium.longPressKeyCode(56, () => {});\n    await app.appium.longPressKeyCode(44, undefined, undefined, () => {});\n\n    const result2 = await app.appium.longPressKeyCode(34, 29474, undefined, () => {});\n    expectType<null>(result2);\n\n    const result3 = await app.appium.hideKeyboard();\n    expectType<boolean>(result3);\n\n    const result4 = await app.appium.isKeyboardShown();\n    expectType<boolean>(result4);\n  });\n\n  it('test reset app commands', async function (app: NightwatchAPI) {\n    const result = await app.appium.resetApp();\n    expectType<null>(result);\n  });\n});\n"
  },
  {
    "path": "types/tests/chromiumClientCommands.test-d.ts",
    "content": "import { expectError, expectType } from 'tsd';\nimport { ExtendDescribeThis, NightwatchAPI } from '..';\n\ntype Metrics = { [metricName: string]: number };\n\n//\n// .setGeolocation\n//\ndescribe('mock geolocation', function () {\n  it('sets the geolocation to Tokyo, Japan and then resets it', () => {\n    browser\n      .setGeolocation({\n        latitude: 35.689487,\n        longitude: 139.691706,\n        accuracy: 100,\n      }) // sets the geolocation to Tokyo, Japan\n      .navigateTo('https://www.gps-coordinates.net/my-location')\n      .pause(3000)\n      .setGeolocation() // resets the geolocation\n      .navigateTo('https://www.gps-coordinates.net/my-location')\n      .pause(3000);\n  });\n\n  it('tests different ways of using setGeolocation', () => {\n    // with all parameters\n    browser.setGeolocation(\n      {\n        latitude: 35.689487,\n        longitude: 139.691706,\n        accuracy: 100,\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        // without any parameter (resets the geolocation)\n        this.setGeolocation();\n        console.log(result.value);\n      }\n    );\n\n    // with only latitude and longitude\n    browser.setGeolocation({\n      latitude: 35.689487,\n      longitude: 139.691706,\n    });\n\n    // with just one parameter\n    expectError(browser.setGeolocation({\n      latitude: 35.689487,\n    }))\n  });\n\n  it('tests setGeolocation with async', async () => {\n    const result = await browser.setGeolocation({\n      latitude: 35.689487,\n      longitude: 139.691706,\n    });\n\n    expectType<null>(result);\n  });\n});\n\n//\n// .captureNetworkRequests\n//\ndescribe('capture network requests', function () {\n  it('captures and logs network requests as they occur', function (this: ExtendDescribeThis<{ requestCount: number }>) {\n    this.requestCount = 1;\n    browser\n      .captureNetworkRequests((requestParams) => {\n        console.log('Request Number:', this.requestCount!++);\n        console.log('Request URL:', requestParams.request.url);\n        console.log('Request method:', requestParams.request.method);\n        console.log('Request headers:', requestParams.request.headers);\n      })\n      .navigateTo('https://www.google.com');\n  });\n\n  it('tests different ways of using captureNetworkRequests', () => {\n    // with all parameters\n    browser.captureNetworkRequests(\n      (requestParams) => {\n        console.log('Request URL:', requestParams.request.url);\n        console.log('Request method:', requestParams.request.method);\n        console.log('Request headers:', requestParams.request.headers);\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        // without any parameter\n        expectError(this.captureNetworkRequests())\n        console.log(result.value);\n      }\n    );\n  });\n\n  it('tests captureNetworkRequests with async', async () => {\n    const result = await browser.captureNetworkRequests(() => {});\n\n    expectType<null>(result);\n  });\n\n  it('captures and logs network requests as they occur', function (this: ExtendDescribeThis<{ requestCount: number }>) {\n    this.requestCount = 1;\n    browser\n      .network.captureRequests((requestParams) => {\n        console.log('Request Number:', this.requestCount!++);\n        console.log('Request URL:', requestParams.request.url);\n        console.log('Request method:', requestParams.request.method);\n        console.log('Request headers:', requestParams.request.headers);\n      })\n      .navigateTo('https://www.google.com');\n  });\n\n  it('tests different ways of using captureRequests', () => {\n    // with all parameters\n    browser.network.captureRequests(\n      (requestParams) => {\n        console.log('Request URL:', requestParams.request.url);\n        console.log('Request method:', requestParams.request.method);\n        console.log('Request headers:', requestParams.request.headers);\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        // without any parameter\n        expectError(this.network.captureRequests())\n        console.log(result.value);\n      }\n    );\n  });\n\n  it('tests captureRequests with async', async () => {\n    const result = await browser.network.captureRequests(() => {});\n\n    expectType<null>(result);\n  });\n});\n\n//\n// .mockNetworkResponse\n//\ndescribe('mock network response', function () {\n  it('intercepts the request made to Google search and mocks its response', function () {\n    browser\n      .mockNetworkResponse('https://www.google.com/', {\n        status: 200,\n        headers: {\n          'Content-Type': 'UTF-8',\n        },\n        body: 'Hello there!',\n      })\n      .navigateTo('https://www.google.com/')\n      .pause(2000);\n  });\n\n  it('tests different ways of using mockNetworkResponse', () => {\n    // with all parameters\n    browser.mockNetworkResponse(\n      'https://www.google.com/',\n      {\n        status: 200,\n        headers: {\n          'Content-Type': 'UTF-8',\n        },\n        body: 'Hello there!',\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        // without any parameter (invalid)\n        expectError(this.mockNetworkResponse())\n        console.log(result.value);\n      }\n    );\n\n    // with no response\n    browser.mockNetworkResponse('https://www.google.com/');\n\n    // with empty response\n    browser.mockNetworkResponse('https://www.google.com/', {});\n\n    // with just one parameter\n    browser.mockNetworkResponse('https://www.google.com/', {\n      body: 'Hello there!',\n    });\n  });\n\n  it('tests mockNetworkResponse with async', async () => {\n    const result = await browser.mockNetworkResponse('https://www.google.com/');\n\n    expectType<null>(result);\n  });\n\n  it('intercepts the request made to Google search and mocks its response', function () {\n    browser\n      .network.mockResponse('https://www.google.com/', {\n        status: 200,\n        headers: {\n          'Content-Type': 'UTF-8',\n        },\n        body: 'Hello there!',\n      })\n      .navigateTo('https://www.google.com/')\n      .pause(2000);\n  });\n\n  it('tests different ways of using mockNetworkResponse', () => {\n    // with all parameters\n    browser.network.mockResponse(\n      'https://www.google.com/',\n      {\n        status: 200,\n        headers: {\n          'Content-Type': 'UTF-8',\n        },\n        body: 'Hello there!',\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        // without any parameter (invalid)\n        expectError(this.network.mockResponse())\n        console.log(result.value);\n      }\n    );\n\n    // with no response\n    browser.network.mockResponse('https://www.google.com/');\n\n    // with empty response\n    browser.network.mockResponse('https://www.google.com/', {});\n\n    // with just one parameter\n    browser.network.mockResponse('https://www.google.com/', {\n      body: 'Hello there!',\n    });\n  });\n\n  it('tests mockResponse with async', async () => {\n    const result = await browser.network.mockResponse('https://www.google.com/');\n\n    expectType<null>(result);\n  });\n});\n\n//\n//.setNetworkConditions\n//\ndescribe('set network conditions', function () {\n  it('sets the network conditions', function () {\n    browser\n      .setNetworkConditions({\n        offline: false,\n        latency: 3000, // Additional latency (ms).\n        download_throughput: 500 * 1024, // Maximal aggregated download throughput.\n        upload_throughput: 500 * 1024, // Maximal aggregated upload throughput.\n      })\n      .navigateTo('https://www.google.com')\n      .pause(2000)\n  });\n\n  it('tests different ways of using setNetworkConditions', () => {\n    // with all parameters\n    browser.setNetworkConditions(\n      {\n        offline: false,\n        latency: 3000, // Additional latency (ms).\n        download_throughput: 500 * 1024, // Maximal aggregated download throughput.\n        upload_throughput: 500 * 1024, // Maximal aggregated upload throughput.\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        // without any parameter (resets the network conditions)\n        // without any parameter (invalid)\n        expectError(this.setNetworkConditions())\n         // missing 'offline' parameter\n        expectError(this.setNetworkConditions({\n          latency: 3000,\n          download_throughput: 500 * 1024,\n          upload_throughput: 500 * 1024,\n        }));\n        // missing 'latency' parameter\n        expectError(this.setNetworkConditions({\n          offline: false,\n          download_throughput: 500 * 1024,\n          upload_throughput: 500 * 1024,\n        }));\n        // missing 'download_throughput' parameter\n        expectError(this.setNetworkConditions({\n          offline: false,\n          latency: 3000,\n          upload_throughput: 500 * 1024,\n        }));\n        // missing 'upload_throughput' parameter\n        expectError(this.setNetworkConditions({\n          offline: false,\n          latency: 3000,\n          download_throughput: 500 * 1024,\n        }));\n\n        console.log(result.value);\n      }\n    );\n\n  });\n\n  it('tests setNetworkConditions with async', async () => {\n    const result = await browser.setNetworkConditions({\n      offline: false,\n      latency: 3000, // Additional latency (ms).\n      download_throughput: 500 * 1024, // Maximal aggregated download throughput.\n      upload_throughput: 500 * 1024, // Maximal aggregated upload throughput.\n    });\n\n    expectType<null>(result);\n  });\n\n  it('sets the network conditions', function () {\n    browser\n      .network.setConditions({\n        offline: false,\n        latency: 3000, // Additional latency (ms).\n        download_throughput: 500 * 1024, // Maximal aggregated download throughput.\n        upload_throughput: 500 * 1024, // Maximal aggregated upload throughput.\n      })\n      .navigateTo('https://www.google.com')\n      .pause(2000)\n  });\n\n  it('tests different ways of using setNetworkConditions', () => {\n    // with all parameters\n    browser.network.setConditions(\n      {\n        offline: false,\n        latency: 3000, // Additional latency (ms).\n        download_throughput: 500 * 1024, // Maximal aggregated download throughput.\n        upload_throughput: 500 * 1024, // Maximal aggregated upload throughput.\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        // without any parameter (resets the network conditions)\n        // without any parameter (invalid)\n        expectError(this.network.setConditions())\n         // missing 'offline' parameter\n        expectError(this.network.setConditions({\n          latency: 3000,\n          download_throughput: 500 * 1024,\n          upload_throughput: 500 * 1024,\n        }));\n        // missing 'latency' parameter\n        expectError(this.network.setConditions({\n          offline: false,\n          download_throughput: 500 * 1024,\n          upload_throughput: 500 * 1024,\n        }));\n        // missing 'download_throughput' parameter\n        expectError(this.network.setConditions({\n          offline: false,\n          latency: 3000,\n          upload_throughput: 500 * 1024,\n        }));\n        // missing 'upload_throughput' parameter\n        expectError(this.network.setConditions({\n          offline: false,\n          latency: 3000,\n          download_throughput: 500 * 1024,\n        }));\n\n        console.log(result.value);\n      }\n    );\n\n  });\n\n  it('tests setConditions with async', async () => {\n    const result = await browser.network.setConditions({\n      offline: false,\n      latency: 3000, // Additional latency (ms).\n      download_throughput: 500 * 1024, // Maximal aggregated download throughput.\n      upload_throughput: 500 * 1024, // Maximal aggregated upload throughput.\n    });\n\n    expectType<null>(result);\n  });\n});\n\n//\n// .setDeviceDimensions\n//\ndescribe('modify device dimensions', function () {\n  it('modifies the device dimensions and then resets it', function () {\n    browser\n      .setDeviceDimensions({\n        width: 400,\n        height: 600,\n        deviceScaleFactor: 50,\n        mobile: true,\n      })\n      .navigateTo('https://www.google.com')\n      .pause(1000)\n      .setDeviceDimensions() // resets the device dimensions\n      .navigateTo('https://www.google.com')\n      .pause(1000);\n  });\n\n  it('tests different ways of using setDeviceDimensions', () => {\n    // with all parameters\n    browser.setDeviceDimensions(\n      {\n        width: 400,\n        height: 600,\n        deviceScaleFactor: 50,\n        mobile: true,\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        // without any parameter (resets the dimensions)\n        this.setDeviceDimensions();\n        console.log(result.value);\n      }\n    );\n\n    // with only width and deviceScaleFactor\n    browser.setDeviceDimensions({\n      width: 400,\n      deviceScaleFactor: 50,\n    });\n\n    // with just one parameter\n    browser.setDeviceDimensions({\n      mobile: true,\n    });\n  });\n\n  it('tests setDeviceDimensions with async', async () => {\n    const result = await browser.setDeviceDimensions();\n\n    expectType<null>(result);\n  });\n});\n\n//\n// .getPerformanceMetrics\n//\ndescribe('collect performance metrics', function () {\n  it('enables the metrics collection, does some stuff and collects the metrics', function () {\n    browser\n      .enablePerformanceMetrics()\n      .navigateTo('https://www.google.com')\n      .getPerformanceMetrics((result) => {\n        if (result.status === 0) {\n          const metrics = result.value;\n          console.log(metrics);\n        }\n      });\n  });\n\n  it('tests different ways of using getPerformanceMetrics', () => {\n    // with all parameters\n    browser.getPerformanceMetrics(function (result) {\n      expectType<NightwatchAPI>(this);\n      // without any parameter\n      this.getPerformanceMetrics();\n\n      if (result.status === 0) {\n        const metrics = result.value;\n        expectType<Metrics>(metrics);\n      }\n    });\n  });\n\n  it('tests getPerformanceMetrics with async', async () => {\n    const result1 = await browser.getPerformanceMetrics();\n    expectType<Metrics>(result1);\n\n    const result2 = await browser\n      .enablePerformanceMetrics()\n      .navigateTo('https://www.google.com')\n      .getPerformanceMetrics();\n    expectType<Metrics>(result2);\n  });\n});\n\n//\n// .enablePerformanceMetrics\n//\ndescribe('collect performance metrics', function () {\n  it('enables the metrics collection, does some stuff and collects the metrics', function () {\n    browser\n      .enablePerformanceMetrics()\n      .navigateTo('https://www.google.com')\n      .getPerformanceMetrics((result) => {\n        if (result.status === 0) {\n          const metrics = result.value;\n          console.log(metrics);\n        }\n      });\n  });\n\n  it('tests different ways of using enablePerformanceMetrics', () => {\n    // with all parameters\n    browser.enablePerformanceMetrics(false, function (result) {\n      expectType<NightwatchAPI>(this);\n      // without any parameter\n      this.enablePerformanceMetrics();\n      console.log(result.value);\n    });\n  });\n\n  it('tests enablePerformanceMetrics with async', async () => {\n    const result1 = await browser.enablePerformanceMetrics();\n    expectType<null>(result1);\n\n    const result2 = await browser.enablePerformanceMetrics(false);\n    expectType<null>(result2);\n  });\n});\n\n//\n// .takeHeapSnapshot\n//\ndescribe('take heap snapshot', function () {\n  it('takes heap snapshot and saves it as snap.heapsnapshot file', function () {\n    browser.navigateTo('https://www.google.com').takeHeapSnapshot('./snap.heapsnapshot');\n  });\n\n  it('tests different ways of using takeHeapSnapshot', () => {\n    // with all parameters\n    browser.takeHeapSnapshot('snap.heapsnapshot', function (result) {\n      expectType<NightwatchAPI>(this);\n      // without any parameter\n      this.takeHeapSnapshot();\n\n      if (result.status === 0) {\n        const snapshot = result.value;\n        expectType<string>(snapshot);\n      }\n    });\n  });\n\n  it('tests takeHeapSnapshot with async', async () => {\n    const result1 = await browser.takeHeapSnapshot();\n    expectType<string>(result1);\n\n    const result2 = await browser.navigateTo('https://www.google.com').takeHeapSnapshot('something.heapsnapshot');\n    expectType<string>(result2);\n  });\n});\n\n//\n// .captureBrowserConsoleLogs\n//\ndescribe('capture console events', function () {\n  it('captures and logs console.log event', function () {\n    browser\n      .captureBrowserConsoleLogs((event) => {\n        console.log(event.type, event.timestamp, event.args[0].value);\n      })\n      .navigateTo('https://www.google.com')\n      .executeScript(function () {\n        console.log('here');\n      }, []);\n  });\n\n  it('captures and logs console.log event using logs ns', function () {\n    browser\n      .logs.captureBrowserConsoleLogs((event) => {\n        console.log(event.type, event.timestamp, event.args[0].value);\n      })\n      .navigateTo('https://www.google.com')\n      .executeScript(function () {\n        console.log('here');\n      }, []);\n  });\n\n  it('tests different ways of using captureBrowserConsoleLogs', () => {\n    // with all parameters\n    browser.captureBrowserConsoleLogs(\n      (event) => {\n        console.log(event.type, event.timestamp, event.args[0].value);\n        expectError(event.context);\n        expectError(event.stackTrace);\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        // without any parameter\n        expectError(this.captureBrowserConsoleLogs())\n        console.log(result.value);\n      }\n    );\n  });\n\n  it('tests captureBrowserConsoleLogs with async', async () => {\n    const result = await browser.captureBrowserConsoleLogs(() => {});\n\n    expectType<null>(result);\n  });\n});\n\n//\n// .captureBrowserExceptions\n//\ndescribe('catch browser exceptions', function () {\n  it('captures the js exceptions thrown in the browser', async function () {\n    await browser.captureBrowserExceptions((event) => {\n      console.log('>>> Exception:', event);\n    });\n\n    await browser.navigateTo('https://duckduckgo.com/');\n\n    const searchBoxElement = await browser.findElement('input[name=q]');\n    await browser.executeScript(\n      function (_searchBoxElement) {\n        expectError(_searchBoxElement.setAttribute('onclick', 'throw new Error(\"Hello world!\")'))\n      },\n      [searchBoxElement]\n    );\n\n    await browser.elementIdClick(searchBoxElement.getId());\n  });\n\n  it('captures the js exceptions thrown in the browser ', async function () {\n    await browser\n      .logs.captureBrowserExceptions((event) => {\n        console.log('>>> Exception:', event);\n      })\n      .navigateTo('https://duckduckgo.com/');\n\n    const searchBoxElement = await browser.findElement('input[name=q]');\n    await browser.executeScript(\n      function (_searchBoxElement) {\n        expectError(_searchBoxElement.setAttribute('onclick', 'throw new Error(\"Hello world!\")'))\n      },\n      [searchBoxElement]\n    );\n\n    await browser.elementIdClick(searchBoxElement.getId());\n  });\n\n  it('tests different ways of using captureBrowserExceptions', () => {\n    // with all parameters\n    browser.captureBrowserExceptions(\n      (event) => {\n        console.log('>>> Exception:', event.timestamp, event.exceptionDetails);\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        // without any parameter\n        expectError(this.captureBrowserExceptions())\n        console.log(result.value);\n      }\n    );\n  });\n\n  it('tests captureBrowserExceptions with async', async () => {\n    const result = await browser.captureBrowserExceptions(() => {});\n\n    expectType<null>(result);\n  });\n});\n"
  },
  {
    "path": "types/tests/clientCommands.test-d.ts",
    "content": "import { expectError, expectType } from 'tsd';\nimport { Cookie, NightwatchAPI, NightwatchCallbackResult, NightwatchElement, NightwatchLogEntry } from '..';\n\n//\n// .navigateTo\n//\ndescribe('Navigation commands demo', function () {\n  test('demoTest', function (browser) {\n    // navigate to new url:\n    browser.navigateTo('https://nightwatchjs.org');\n    // with callback\n    browser.navigateTo('https://nightwatchjs.org', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n      expectError(this.navigateTo());\n    });\n  });\n\n  test('demoTestAsync', async function (browser) {\n    const result = await browser.navigateTo('https://nightwatchjs.org');\n    expectType<null>(result);\n  });\n});\n\n//\n// .openNewWindow\n//\ndescribe('openNewWindow demo', function () {\n  test('demo test', function (browser) {\n    // open a new window tab (default)\n    browser.openNewWindow('tab', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n\n    // open a new window\n    browser.openNewWindow('window', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.openNewWindow('window');\n    expectType<null>(result);\n  });\n});\n\n//\n// .closeWindow\n//\ndescribe('closeWindow demo', function () {\n  test('demo test', function (browser) {\n    browser.closeWindow(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.closeWindow();\n    expectType<null>(result);\n  });\n});\n\n//\n// .fullscreenWindow\n//\ndescribe('fullscreenWindow demo', function () {\n  test('demo test', function (browser) {\n    browser.fullscreenWindow(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.fullscreenWindow();\n    expectType<null>(result);\n  });\n});\n\n//\n// .minimizeWindow\n//\ndescribe('minimizeWindow demo', function () {\n  test('demo test', function (browser) {\n    browser.minimizeWindow(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.minimizeWindow();\n    expectType<null>(result);\n  });\n});\n\n//\n// .deleteCookie\n//\ndescribe('deleteCookie demo', function () {\n  test('demo test', function (browser) {\n    browser\n      .navigateTo('https://www.google.com')\n      .setCookie({\n        name: 'test_cookie',\n        value: 'test_value',\n      })\n      .deleteCookie('test_cookie', function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.deleteCookie('test_cookie');\n    expectType<null>(result);\n  });\n});\n\n//\n// .deleteCookies\n//\ndescribe('deleteCookies demo', function () {\n  test('demo test', function (browser) {\n    browser\n      .navigateTo('https://www.google.com')\n      .setCookie({\n        name: 'test_cookie',\n        value: 'test_value',\n      })\n      .deleteCookies(function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.deleteCookies();\n    expectType<null>(result);\n  });\n});\n\n//\n// .end\n//\ndescribe('end command demo', function () {\n  test('demo test', function (browser) {\n    browser.end(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n});\n\n//\n// .getCookie\n//\ndescribe('getCookie command demo', function () {\n  test('demo test', function (browser) {\n    browser\n      .navigateTo('https://www.google.com')\n      .setCookie({\n        name: 'test_cookie',\n        value: 'test_value',\n      })\n      .getCookie('test_cookie', function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<Cookie>>(result);\n      });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getCookie('test_cookie');\n    expectType<Cookie>(result);\n  });\n});\n\n//\n// .setCookie\n//\ndescribe('setCookie command demo', function () {\n  test('demo test', function (browser) {\n    browser.navigateTo('https://www.google.com').setCookie(\n      {\n        name: 'test_cookie',\n        value: 'test_value',\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      }\n    );\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.setCookie({\n      name: 'test_cookie',\n      value: 'test_value',\n    });\n    expectType<null>(result);\n  });\n});\n\n//\n// .getLog\n//\ndescribe('getLog command demo', function () {\n  test('demo test', function () {\n    browser.getLog('browser', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchLogEntry[]>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getLog('browser');\n    expectType<NightwatchLogEntry[]>(result);\n  });\n});\n\n//\n// .getCurrentUrl\n//\ndescribe('getCurrentUrl command demo', function () {\n  test('demo test', function () {\n    browser.navigateTo('https://www.nightwatchjs.org').getCurrentUrl(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.navigateTo('https://www.nightwatchjs.org').getCurrentUrl();\n    expectType<string>(result);\n  });\n});\n\n//\n// .getTitle\n//\ndescribe('getTitle command demo', function () {\n  test('demo test', function () {\n    browser.navigateTo('https://www.ecosia.org').getTitle(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<string>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.navigateTo('https://www.ecosia.org').getTitle();\n    expectType<string>(result);\n  });\n});\n\n//\n// .isLogAvailable\n//\ndescribe('isLogAvailable command demo', function () {\n  test('demo test', function () {\n    browser.isLogAvailable('browser', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<boolean>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.isLogAvailable('browser');\n    expectType<boolean>(result);\n  });\n});\n\n//\n// .resizeWindow\n//\ndescribe('resizeWindow command demo', function () {\n  test('demo test', function () {\n    browser.navigateTo('https://www.ecosia.org').resizeWindow(1000, 500, function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.resizeWindow(1000, 800);\n    expectType<null>(result);\n  });\n});\n\n//\n// .screenshot\n//\ndescribe('screenshot command demo', function () {\n  test('demo test', function (browser) {\n    browser\n      .screenshot(function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<string>>(result);\n      })\n      .screenshot(true, function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<string>>(result);\n      });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.screenshot();\n    expectType<string>(result);\n\n    const result2 = await browser.screenshot(true);\n    expectType<string>(result2);\n  });\n});\n\n//\n// .saveScreenshot\n//\ndescribe('saveScreenshot command demo', function () {\n  test('async demo test', async function (browser) {\n    const result = await browser.saveScreenshot('bcd.jpg');\n    expectType<string>(result);\n  });\n});\n\n//\n// .setCookie\n//\ndescribe('setCookie command demo', function () {\n  test('demo test', function () {\n    return browser.navigateTo('https://www.ecosia.org').setCookie(\n      {\n        name: 'testCookie',\n        value: '',\n      },\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      }\n    );\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.setCookie({\n      name: 'testCookie',\n      value: '',\n    });\n    expectType<null>(result);\n  });\n});\n\n//\n// .setWindowPosition\n//\ndescribe('setWindowPosition command demo', function () {\n  test('demo test', function () {\n    browser.setWindowPosition(0, 0, function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.setWindowPosition(0, 0);\n    expectType<null>(result);\n  });\n});\n\n//\n// .setWindowRect\n//\ndescribe('setWindowRect command demo', function () {\n  test('demo test', function () {\n    browser.setWindowRect({ x: 0, y: 0, width: 500, height: 500 }, function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n  test('async demo test', async function (browser) {\n    const result = await browser.setWindowRect({ x: 0, y: 0, width: 500, height: 500 });\n    expectType<null>(result);\n  });\n});\n\n//\n// .setWindowSize\n//\ndescribe('setWindowSize command demo', function () {\n  test('demo test', function () {\n    browser.setWindowSize(500, 500, function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.setWindowSize(500, 500);\n    expectType<null>(result);\n  });\n});\n\n//\n// switchWindow\n//\ndescribe('switchWindow command demo', function () {\n  test('async demo test', async function (browser) {\n    const handle = await browser.windowHandle();\n    const result = await browser.switchWindow(handle);\n    expectType<null>(result);\n  });\n});\n\n//\n// switchToWindow\n//\ndescribe('switchToWindow command demo', function () {\n  test('async demo test', async function (browser) {\n    const handle = await browser.windowHandle();\n    const result = await browser.switchToWindow(handle);\n    expectType<null>(result);\n  });\n});\n\n//\n// .init\n//\ndescribe('init command demo', function () {\n  test('demo test', function () {\n    browser.init('https://www.google.com', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n});\n\n//\n// .waitUntil\n//\ndescribe('waitUntil command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function () {\n    browser.waitUntil(\n      async function () {\n        expectType<NightwatchAPI>(this);\n        return true;\n      },\n      5000,\n      5000,\n      function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      }\n    );\n  });\n  it('demo Test 2', function() {\n    browser\n      .url('https://nightwatchjs.org')\n      .waitUntil(async function() {\n        const title = await this.execute(function() {\n          return document.title;\n        });\n\n        return title === 'Nightwatch.js';\n      }, 1000, 100, 'some message');\n  });\n  test('async demo test', async function () {\n    const result = await browser.waitUntil(async function () {\n      return true;\n    });\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .axeInject\n//\ndescribe('axeInject test', function () {\n  test('async demo test', async function (browser) {\n    const result = await browser.axeInject();\n    expectType<null>(result);\n  });\n  after((browser) => browser.end());\n});\n\n//\n// .injectScript\n//\ndescribe('injectScript command demo', function() {\n    before(browser => browser.url('https://www.google.com/'));\n\n    test('demo test', function(browser) {\n        browser.injectScript('<script-url>', function(result) {\n            expectType<NightwatchAPI>(this);\n            expectType<NightwatchCallbackResult<NightwatchElement>>(result);\n        });\n        browser.injectScript('<script-url>', 'id', function(result) {\n            expectType<NightwatchAPI>(this);\n            expectType<NightwatchCallbackResult<NightwatchElement>>(result);\n        });\n    });\n\n    test('async demo test', async function(browser) {\n        const result = await browser.injectScript('<script-url>');\n        expectType<NightwatchElement>(result);\n\n        const result2 = await browser.injectScript('<script-url>', 'id');\n        expectType<NightwatchElement>(result2);\n    });\n\n    after(browser => browser.end());\n});\n\n//\n// .perform\n//\ndescribe('perform command demo', function() {\n  test('demo test', function() {\n    browser.perform(async function() {\n      expectType<NightwatchAPI>(this);\n    });\n    browser.perform(function() {\n      expectType<NightwatchAPI>(this);\n    });\n    browser.perform(function(done: () => void) {\n      expectType<NightwatchAPI>(this);\n      done();\n    });\n    browser.perform(function(client: NightwatchAPI, done: () => void) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchAPI>(client);\n      done();\n    });\n  });\n\n  test('async demo test', async function() {\n    const result = await browser.perform(function() {\n      expectType<NightwatchAPI>(this); \n      return '';\n    })\n    expectType<string>(result);\n\n    const result2 = await browser.perform(async function() {\n      expectType<NightwatchAPI>(this); \n      return true;\n    })\n    expectType<boolean>(result2);\n\n    const result3 = await browser.perform(function(done: (result?: number) => void) {\n      expectType<NightwatchAPI>(this);\n      done(2);\n    });\n    expectType<number>(result3);\n\n    const result4 = await browser.perform(function(client: NightwatchAPI, done: (result?: string) => void) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchAPI>(client);\n\n      client.getTitle((result) => {\n        done(result);\n      });\n    });\n    expectType<string>(result4);\n  });\n});\n"
  },
  {
    "path": "types/tests/component.test-d.ts",
    "content": "import { NightwatchTests } from '..';\n\nconst componentTesting: NightwatchTests = {\n  'Demo component testing': () => {\n    const reactComponent = browser.mountReactComponent('react.tsx');\n    browser.expect.element(reactComponent).to.be.present;\n    browser.expect.element('h1').text.to.equal('Hello World');\n  },\n};\n"
  },
  {
    "path": "types/tests/customCommands.test-d.ts",
    "content": "import {expectType} from 'tsd';\nimport {CustomCommandInstance, NightwatchCallbackResult, NightwatchCustomCommandsModel} from '..';\n\nexport class AngularCommand implements NightwatchCustomCommandsModel {\n  async command(this: CustomCommandInstance, listName: string, cb = function<T>(r: T) {return r}) {\n    // Script to be executed in the browser\n    const script = function(listName: string) {\n      // executed in the browser context\n      // eslint-disable-next-line\n      var elements = document.querySelectorAll('*[ng-repeat$=\"'+listName+'\"]');\n\n      if (elements) {return elements}\n\n      return null;\n    };\n\n    // Arguments to be passed to the script function above\n    const args: [string] = [listName];\n\n    // Callback to be called when the script finishes its execution,\n    // with the result returned by the script passed as argument.\n    const callback = async function(result: any) {\n      const cbResult = await cb(result);\n\n      if (cbResult.value) {\n        return cbResult.value;\n      }\n\n      return cbResult;\n    };\n\n    // Execute the script defined above, along with arguments and\n    // the callback function.\n    await this.api.executeScript(script, args, callback);\n\n\n    // CUSTOM COMMAND WITH `this.httpRequest` EXAMPLE\n    const response = await this.httpRequest({\n      path: '/session/:sessionId/url',\n      sessionId: this.api.sessionId,\n      method: 'POST',\n      data: {\n        url: 'https://nightwatchjs.org'\n      }\n    });\n    expectType<unknown>(response);\n\n    // CUSTOM COMMAND WITH `this.transportActions` EXAMPLE (still incomplete)\n    const currentUrl = await (this.transportActions as TransportActions).getCurrentUrl();\n    expectType<NightwatchCallbackResult<string>>(currentUrl);\n\n    this.complete('hello', 1, true, {value: null});\n  }\n}\n\ninterface TransportActions {\n  getCurrentUrl(): Promise<NightwatchCallbackResult<string>>;\n}\n"
  },
  {
    "path": "types/tests/describe.test-d.ts",
    "content": "import { ExtendDescribeThis } from '..';\nimport {FileDetector} from 'selenium-webdriver/remote';\n\ndescribe('Ecosia', () => {\n  before((browser) => browser.url('https://www.ecosia.org/'));\n\n  it('Demo test ecosia.org', () => {\n    // Setting network conditions before the actual test\n    browser.setNetworkConditions({\n      offline: false,\n      latency: 5, // Additional latency (ms).\n      download_throughput: 500 * 1024, // Maximal aggregated download throughput.\n      upload_throughput: 500 * 1024, // Maximal aggregated upload throughput.\n    });\n\n    // https://www.selenium.dev/selenium/docs/api/javascript/WebDriver.html#setFileDetector\n    browser.driver.setFileDetector(new FileDetector());\n\n    browser\n      .waitForElementVisible('body')\n      .assert.titleContains('Ecosia')\n      .assert.titleContains('Ecosia')\n      .assert.visible('input[type=search]')\n      .setValue('input[type=search]', 'nightwatch')\n      .assert.visible('button[type=submit]')\n      .click('button[type=submit]');\n  });\n\n  xit('this test will be skipped', (browser) => {\n    browser.waitForElementVisible('body');\n  });\n\n  after((browser) => browser.end());\n});\n\nxdescribe('whole describle block will be skipped', () => {\n  test('ecosia', () => {\n    browser.url('https://ecosia.org').end();\n  });\n});\n\n//\n// test custom this\n//\n\ninterface CustomThis {\n  bodySelector: string;\n}\n\ndescribe('Async Ecosia with custom this', function (this: ExtendDescribeThis<CustomThis>) {\n  this.tags = 'ecosia';\n  this.desiredCapabilities = {\n    browserName: 'chrome',\n  };\n  this.retries(2);\n\n  before(function (this: ExtendDescribeThis<CustomThis>, browser, done) {\n    browser.url('https://www.ecosia.org/');\n    this.bodySelector = 'body';\n    done();\n  });\n\n  it('Demo test ecosia.org', async (browser) => {\n    browser.waitForElementVisible(this.bodySelector!);\n  });\n\n  after((browser) => browser.end());\n});\n"
  },
  {
    "path": "types/tests/elementCommands.test-d.ts",
    "content": "import { expectType } from 'tsd';\nimport { JSON_WEB_OBJECT, NightwatchSizeAndPosition, ElementResult, NightwatchAPI, NightwatchCallbackResult, ElementGlobal } from '..';\n\n//\n// .check\n//\ndescribe('check command demo', function () {\n  test('demo test', function () {\n    browser\n      .url('https://www.selenium.dev/selenium/web/formPage.html')\n      .waitForElementVisible('#checkbox-with-label')\n      .check('#checkbox-with-label', function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      })\n      .expect.element('#checkbox-with-label').to.be.selected;\n    \n    // Should not uncheck the checkbox if .check is rerun on the same element\n    browser\n      .check('#checkbox-with-label')\n      .expect.element('#checkbox-with-label').to.be.selected\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser\n      .url('https://www.selenium.dev/selenium/web/formPage.html')\n      .waitForElementVisible('#checkbox-with-label')\n      .check('#checkbox-with-label');\n    expectType<null>(result);\n  });\n});\n\n//\n// .uncheck\n//\ndescribe('uncheck command demo', function () {\n  test('demo test', function () {\n    browser\n      .url('https://www.selenium.dev/selenium/web/formPage.html')\n      .waitForElementVisible('#checkbox-with-label')\n      .click('#checkbox-with-label')\n      .assert.selected('#checkbox-with-label')\n      .uncheck('#checkbox-with-label', function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      })\n      .expect.element('#checkbox-with-label').to.not.be.selected;\n    \n    // Should not check the checkbox if .check is rerun on the same element\n    browser\n      .uncheck('#checkbox-with-label')\n      .expect.element('#checkbox-with-label').to.not.be.selected\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser\n      .url('https://www.selenium.dev/selenium/web/formPage.html')\n      .waitForElementVisible('#checkbox-with-label')\n      .uncheck('#checkbox-with-label');\n    expectType<null>(result);\n  });\n});\n\n//\n// .clearValue\n//\ndescribe('clearValue Command demo', function () {\n  test('demo test', function () {\n    browser\n      .url('https://google.com')\n      .waitForElementVisible('input[type=text]')\n      .setValue('input[type=text]', 'nightwatch.js')\n      .clearValue('input[type=text]', function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      })\n      .expect.element('input[type=text]')\n      .text.to.equal('');\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser\n      .url('https://google.com')\n      .waitForElementVisible('input[type=text]')\n      .setValue('input[type=text]', 'nightwatch.js')\n      .clearValue('input[type=text]');\n    expectType<null>(result);\n  });\n});\n\n//\n// .click\n//\ndescribe('click Command demo', function () {\n  test('demo test', function () {\n    browser\n      .url('https://google.com')\n      .waitForElementVisible('input[type=text]')\n      .setValue('input[type=text]', 'nightwatch.js')\n      .click('input[type=submit]', function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser\n      .url('https://google.com')\n      .waitForElementVisible('input[type=text]')\n      .setValue('input[type=text]', 'nightwatch.js')\n      .click('input[type=submit]');\n    expectType<null>(result);\n  });\n});\n\n//\n// .getAttribute\n//\ndescribe('getAttribute command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function () {\n    browser.getAttribute('input[type=text]', 'title', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string | null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getAttribute('input[type=text]', 'title');\n    expectType<string | null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .getCssProperty\n//\ndescribe('getCssProperty command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function () {\n    browser.getCssProperty('input[type=text]', 'background-color', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getCssProperty('input[type=text]', 'background-color');\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .getElementSize\n//\ndescribe('getElementSize command demo', function () {\n  test('demo test', function () {\n    browser.url('https://www.ecosia.org/').getElementSize('#navbartop', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<NightwatchSizeAndPosition>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.url('https://www.ecosia.org/').getElementSize('#__nuxt');\n    expectType<NightwatchSizeAndPosition>(result);\n  });\n});\n\n//\n// .getLocation\n//\ndescribe('getLocation command demo', function () {\n  test('demo test', function () {\n    browser.url('https://www.ecosia.org/').getLocation('#__nuxt', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<NightwatchSizeAndPosition>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.url('https://www.ecosia.org/').getLocation('#__nuxt');\n    expectType<NightwatchSizeAndPosition>(result);\n  });\n});\n\n//\n// .getTagName\n//\ndescribe('getTagName command demo', function () {\n  before((browser) => browser.url('https://www.ecosia.org/'));\n\n  test('demo test', function () {\n    browser.getTagName('#__nuxt', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getTagName('#__nuxt');\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .getText\n//\ndescribe('getText command demo', function () {\n  before((browser) => browser.url('https://nightwatchjs.org/'));\n\n  test('demo test', function () {\n    browser.getText('#top-section', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getText('#top-section');\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .getValue\n//\ndescribe('getValue command demo', function () {\n  before((browser) => browser.url('https://google.com/'));\n\n  test('demo test', function () {\n    browser.setValue('input[type=text]', 'nightwatchjs').getValue('input[type=text]', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getValue('input[type=text]');\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .getShadowRoot\n//\ndescribe('getShadowRoot command demo', function () {\n  test('demo test', function () {\n    browser.getShadowRoot('input[type=text]', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<ElementGlobal | null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getShadowRoot('input[type=text]');\n    expectType<ElementGlobal | null>(result);\n\n    const result2 = await browser.getShadowRoot(await element('selector').getWebElement());\n    expectType<ElementGlobal | null>(result2);\n  });\n});\n\n//\n// .isVisible\n//\ndescribe('isVisible command demo', function () {\n  before((browser) => browser.url('https://google.com/'));\n  test('demo test', function () {\n    browser.isVisible('input[type=text]', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<boolean>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.isVisible('input[type=text]');\n    expectType<boolean>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .isPresent\n//\ndescribe('isPresent command demo', function () {\n  before((browser) => browser.url('https://google.com/'));\n  test('demo test', function () {\n    browser.isPresent('input[type=text]', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<boolean>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.isPresent('input[type=text]');\n    expectType<boolean>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .setValue\n//\ndescribe('setValue command demo', function () {\n  before((browser) => browser.url('https://google.com/'));\n  test('demo test', function () {\n    browser.setValue('input[type=text]', 'nightwatchjs', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.setValue('input[type=text]', 'nightwatchjs');\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .sendKeys\n//\ndescribe('sendKeys command demo', function () {\n  before((browser) => browser.url('https://google.com/'));\n\n  test('demo test', function () {\n    browser.sendKeys('input[type=text]', 'nightwatchjs', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.setValue('input[type=text]', ['nightwatchjs', browser.Keys.ENTER]);\n    expectType<null>(result);\n  });\n  after((browser) => browser.end());\n});\n\n//\n// .setPassword\n//\ndescribe('setPassword command demo', function () {\n  before((browser) => browser.url('https://google.com/'));\n  test('demo test', function () {\n    browser.setPassword('input[type=text]', 'nightwatchjs', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.setPassword('input[type=text]', ['nightwatchjs', browser.Keys.ENTER]);\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .setAttribute\n//\ndescribe('setAttribute command demo', function () {\n  before((browser) => browser.url('https://google.com/'));\n  test('demo test', function () {\n    browser.setAttribute('input[type=text]', 'disabled', 'true', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<boolean>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.setAttribute('input[type=text]', 'disabled', 'false');\n    expectType<boolean>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .isEnabled\n//\ndescribe('isEnabled command demo', function () {\n  before((browser) => browser.url('https://google.com/'));\n  test('demo test', function () {\n    browser.setAttribute('input[type=text]', 'disabled', 'true').isEnabled('input[type=text]', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<boolean>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.isEnabled('input[type=text]');\n    expectType<boolean>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .getElementProperty\n//\ndescribe('getElementProperty command demo', function () {\n  before((browser) => browser.url('https://google.com/'));\n  test('demo test', function () {\n    browser.getElementProperty('input[type=text]', 'disabled', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<any>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getElementProperty('input[type=text]', 'disabled');\n    expectType<any>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .findElement\n//\ndescribe('findElement command demo', function () {\n  before((browser) => browser.url('https://google.com/'));\n  test('demo test', function () {\n    browser.findElement('input[type=text]', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<JSON_WEB_OBJECT>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.findElement('input[type=text]');\n    expectType<JSON_WEB_OBJECT>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .getElementRect\n//\ndescribe('getElementRect command demo', function () {\n  before((browser) => browser.url('https://www.ecosia.org/'));\n\n  test('demo test', function () {\n    browser.getElementRect('#__nuxt', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<NightwatchSizeAndPosition>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getElementRect('#__nuxt');\n    expectType<NightwatchSizeAndPosition>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// getAriaRole\n//\ndescribe('getAriaRole command demo', function () {\n  before((browser) => browser.url('https://www.ecosia.org/'));\n\n  test('demo test', function () {\n    browser.getAriaRole('#__nuxt', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getAriaRole('#__nuxt');\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .getAccessibleName\n//\ndescribe('getAccessibleName command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function () {\n    browser.getAccessibleName('input[type=text]', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.getAccessibleName('input[type=text]');\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// waitForElementVisible\n//\ndescribe('waitForElementVisible command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function () {\n    browser.waitForElementVisible('input[type=text]', undefined, undefined, true, function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<boolean>>(result);\n    });\n\n    // - with no arguments; in this case a global default timeout is used\n    browser.waitForElementVisible('body');\n\n    // specify the locate strategy (css selector/xpath) as the first argument\n    browser.waitForElementVisible('css selector', '#dialog');\n\n    // with custom output message - the locate strategy is required\n    browser.waitForElementVisible('css selector', '#dialog', 'The dialog container is removed.');\n  \n    // - with a global default timeout and a callback\n    browser.waitForElementVisible('body', function() {});\n  \n    // - with a global default timeout, a callback, and a custom message\n    browser.waitForElementVisible('body', function() {}, 'test message');\n  \n    // - with a global default timeout a custom message\n    browser.waitForElementVisible('body', 'test message');\n  \n    // - with only the timeout\n    browser.waitForElementVisible('body', 500);\n  \n    // - with a timeout and a custom message\n    browser.waitForElementVisible('body', 500, 'test message');\n  \n    // - with a timeout and a callback\n    browser.waitForElementVisible('body', 500, function() {});\n  \n    // - with a timeout and a custom abortOnFailure\n    browser.waitForElementVisible('body', 500, true);\n  \n    // - with a timeout, a custom abortOnFailure, and a custom message\n    browser.waitForElementVisible('body', 500, true, 'test message');\n  \n    // - with a timeout, a custom abortOnFailure, and a callback\n    browser.waitForElementVisible('body', 500, true, function() {});\n  \n    // - with a timeout, a custom abortOnFailure, a callback and a custom message\n    browser.waitForElementVisible('body', 500, true, function() {}, 'test message');\n  \n    // - with a timeout, a custom reschedule interval, and a callback\n    browser.waitForElementVisible('body', 500, 100, function() {});\n  \n    // - with a timeout, a custom rescheduleInterval, and a custom abortOnFailure\n    browser.waitForElementVisible('body', 500, 100, false);\n\n    // - with a timeout, a custom rescheduleInterval, a custom abortOnFailure, and a custom message\n    browser.waitForElementVisible('body', 500, 100, false, 'test message');\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.waitForElementVisible('input[type=text]', undefined, undefined, true);\n    expectType<true | Error>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .waitForElementPresent\n//\ndescribe('waitForElementPresent command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function () {\n    browser.waitForElementPresent('input[type=text]', undefined, undefined, undefined, function (result) {\n      expectType<NightwatchAPI>(this);\n\n      expectType<NightwatchCallbackResult<null | ElementResult[]>>(result);\n    });\n\n    // - with no arguments; in this case a global default timeout is used\n    browser.waitForElementPresent('body');\n\n    // specify the locate strategy (css selector/xpath) as the first argument\n    browser.waitForElementPresent('css selector', '#dialog');\n\n    // with custom output message - the locate strategy is required\n    browser.waitForElementPresent('css selector', '#dialog', 'The dialog container is removed.');\n  \n    // - with a global default timeout and a callback\n    browser.waitForElementPresent('body', function() {});\n  \n    // - with a global default timeout, a callback, and a custom message\n    browser.waitForElementPresent('body', function() {}, 'test message');\n  \n    // - with a global default timeout a custom message\n    browser.waitForElementPresent('body', 'test message');\n  \n    // - with only the timeout\n    browser.waitForElementPresent('body', 500);\n  \n    // - with a timeout and a custom message\n    browser.waitForElementPresent('body', 500, 'test message');\n  \n    // - with a timeout and a callback\n    browser.waitForElementPresent('body', 500, function() {});\n  \n    // - with a timeout and a custom abortOnFailure\n    browser.waitForElementPresent('body', 500, true);\n  \n    // - with a timeout, a custom abortOnFailure, and a custom message\n    browser.waitForElementPresent('body', 500, true, 'test message');\n  \n    // - with a timeout, a custom abortOnFailure, and a callback\n    browser.waitForElementPresent('body', 500, true, function() {});\n  \n    // - with a timeout, a custom abortOnFailure, a callback and a custom message\n    browser.waitForElementPresent('body', 500, true, function() {}, 'test message');\n  \n    // - with a timeout, a custom reschedule interval, and a callback\n    browser.waitForElementPresent('body', 500, 100, function() {});\n  \n    // - with a timeout, a custom rescheduleInterval, and a custom abortOnFailure\n    browser.waitForElementPresent('body', 500, 100, false);\n\n    // - with a timeout, a custom rescheduleInterval, a custom abortOnFailure, and a custom message\n    browser.waitForElementPresent('body', 500, 100, false, 'test message');\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.waitForElementPresent('input[type=text]');\n    expectType<ElementResult[] | Error>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .dragAndDrop\n//\ndescribe('dragAndDrop command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('hello', function () {\n    browser.dragAndDrop('input[type=text]', { x: 50, y: 50 }, function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.dragAndDrop('input[type=text]', { x: 50, y: 50 });\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n"
  },
  {
    "path": "types/tests/expect.test-d.ts",
    "content": "import { expectAssignable, expectError, expectNotAssignable, expectNotType, expectType } from 'tsd';\nimport { ExpectElement, NightwatchAPI, NightwatchExpectResult } from '..';\n\n// Chai expect() library\nit('test expect()', async () => {\n  expectType<Chai.Assertion>(expect('Nightwatch.js').to.contain('Nightwatch'));\n  expectType<Chai.Assertion>(expect(2).to.equal(2));\n  expectType<Chai.Assertion>(expect(function () {}).to.not.throw());\n  expectType<Chai.Assertion>(expect({a: 2, b: 1}).to.have.property('b'));\n  expectType<Chai.Assertion>(expect([1, 2]).to.be.an('array').that.does.not.include(3));\n  expectType<Chai.Assertion>(expect([1, 2, 3]).to.be.an('array').that.does.include(3));\n\n  // if element is passed to expect\n  const expectAssert = expect(element('selector')).text.equal('something')\n  expectNotType<Chai.Assertion>(expectAssert);;\n  expectNotAssignable<Chai.Assertion>(expectAssert);\n  expectAssignable<ExpectElement>(expectAssert);\n  expectAssignable<ExpectElement>(expect(by.xpath('//tagname')).text.equal('something'));\n  expectAssignable<ExpectElement>(expect(await element('selector').getWebElement()).text.equal('something'))\n  expectAssignable<ExpectElement>(expect(await browser.findElement('selector')).text.equal('something'));;\n});\n\n// Expect test for language chains\nit('expect.equal(value)/.contain(value)/.match(regex)', () => {\n  browser.expect.element('#main').text.to.equal('The Night Watch');\n  browser.expect.element('#main').text.to.contain('The Night Watch');\n  browser.expect.element('#main').to.have.css('display').which.equals('block');\n\n  // with section\n  browser.expect.section('@main').text.to.equal('The Night Watch');\n  browser.expect.section('@main').text.to.contain('The Night Watch');\n  browser.expect.section('@main').to.have.css('display').which.equals('block');\n});\n\nit('expect.startWith(value)/.endWith(value)', () => {\n  browser.expect.element('#main').text.to.endWith('Watch');\n  browser.expect.element('#main').text.to.startWith('The');\n});\n\nit('expect.not', () => {\n  browser.expect.element('#main').text.to.not.equal('The Night Watch');\n  browser.expect.element('#main').text.to.not.contain('The Night Watch');\n  browser.expect.element('#main').to.have.css('display').which.does.not.equal('block');\n});\n\nit('expect.before(ms)/.after(ms)', () => {\n  browser.expect.element('#main').text.to.contain('The Night Watch').before(1000);\n  browser.expect.element('#main').text.to.not.contain('The Night Watch').after(500);\n});\n\nit('expect.cookie()', () => {\n  browser.expect.cookie('cookie-name').to.contain('cookie-value');\n  browser.expect.cookie('cookie-name').to.match(/regex/);\n  browser.expect.cookie('loginCookie', 'example.org').to.contain('cookie-value');\n});\n\ndescribe('expect.element()', () => {\n  it('have .a(type)', () => {\n    browser.expect.element('#q').to.be.an('input');\n    browser.expect.element('#q').to.be.an('input', 'Testing if #q is an input');\n    browser.expect.element('#w').to.be.a('span');\n  });\n\n  it('have .active()', () => {\n    browser.expect.element('#main').to.be.active;\n    browser.expect.element('#main').to.not.be.active;\n    browser.expect.element('#main').to.be.active.before(100);\n    // with two properties together\n    browser.expect.element('#main').to.be.active.and.visible;\n  });\n\n  it('have .attribute()', () => {\n    browser.expect.element('body').to.have.attribute('data-attr');\n    browser.expect.element('body').to.not.have.attribute('data-attr');\n    browser.expect.element('body').to.not.have.attribute('data-attr', 'Testing if body does not have data-attr');\n    browser.expect.element('body').to.have.attribute('data-attr').before(100);\n    browser.expect.element('body').to.have.attribute('data-attr').equals('some attribute');\n    browser.expect.element('body').to.have.attribute('data-attr').not.equals('other attribute');\n    browser.expect.element('body').to.have.attribute('data-attr').which.contains('something');\n    browser.expect\n      .element('body')\n      .to.have.attribute('data-attr')\n      .which.matches(/^something\\ else/);\n    // with assertion before the attribute property\n    browser.expect.element('body').to.contain('Search').with.attribute('placeholder');\n    // with multiple properties\n    browser.expect.element('input[name=q]').to.have.attribute('class').and.attribute('id').contain('searchbox');\n  });\n\n  it('have .css(property)', () => {\n    browser.expect.element('#main').to.have.css('display');\n    browser.expect.element('#main').to.have.css('display', 'Testing for display');\n    browser.expect.element('#main').to.not.have.css('display');\n    browser.expect.element('#main').to.have.css('display').before(100);\n    browser.expect.element('#main').to.have.css('display').which.eq('block');\n    browser.expect.element('#main').to.have.css('display').which.contains('some value');\n    browser.expect\n      .element('#main')\n      .to.have.css('display')\n      .which.matches(/some\\ value/);\n  });\n\n  it('have .enabled', () => {\n    browser.expect.element('#weblogin').to.be.enabled;\n    browser.expect.element('#main').to.not.be.enabled;\n    browser.expect.element('#main').to.be.enabled.before(100);\n  });\n\n  it('have .present', () => {\n    browser.expect.element('#main').to.be.present;\n    browser.expect.element('#main').to.not.be.present;\n    browser.expect.element('#main').to.be.present.before(100);\n  });\n\n  it('have .property', () => {\n    browser.expect.element('body').to.have.property('className').equals('test-class');\n    browser.expect\n      .element('body')\n      .to.have.property('className')\n      .matches(/^something\\ else/);\n    browser.expect.element('body').to.not.have.property('classList').equals('test-class');\n    browser.expect.element('body').to.have.property('classList').deep.equal(['class-one', 'class-two']);\n    browser.expect.element('body').to.have.property('classList').contain('class-two');\n    browser.expect.element('body').to.have.domProperty('classList').contain('class-two');\n  });\n\n  it('have .selected', () => {\n    browser.expect.element('#main').to.be.selected;\n    browser.expect.element('#main').to.not.be.selected;\n    browser.expect.element('#main').to.be.selected.before(100);\n  });\n\n  it('have .text', () => {\n    browser.expect.element('#main').text.to.equal('The Night Watch');\n    browser.expect.element('#main').text.to.not.equal('The Night Watch');\n    browser.expect.element('#main').text.to.equal('The Night Watch').before(100);\n    browser.expect.element('#main').text.to.contain('The Night Watch');\n    browser.expect.element('#main').text.to.match(/The\\ Night\\ Watch/);\n  });\n\n  it('have .value', () => {\n    browser.expect.element('#q').to.have.value.that.equals('search');\n    browser.expect.element('#q').to.have.value.not.equals('search');\n    browser.expect.element('#q').to.have.value.which.contains('search');\n    browser.expect.element('#q').to.have.value.which.matches(/search/);\n  });\n\n  it('have .visible', () => {\n    browser.expect.element('#main').to.be.visible;\n    browser.expect.element('#main').to.not.be.visible;\n    browser.expect.element('#main').to.be.visible.before(100);\n  });\n\n  it('have .domProperty(property)', () => {\n    browser.expect.element('#main').to.have.domProperty('classList');\n    browser.expect.element('#main').to.have.domProperty('classList', 'Testing DOM property classList exists');\n    browser.expect.element('#main').to.not.have.domProperty('classList');\n    browser.expect.element('#main').to.have.domProperty('classList').before(100);\n    browser.expect.element('#main').to.have.domProperty('classList').which.equals('js-search-input');\n    browser.expect.element('#main').to.have.domProperty('classList').which.includes('search');\n    browser.expect\n      .element('#main')\n      .to.have.domProperty('classList')\n      .which.matches(/search/);\n  });\n});\n\ndescribe('expect.section()', () => {\n  // Just check if it contains some properties of `expect.element()`.\n  it('have .present', () => {\n    browser.expect.section('@main').to.be.present;\n    browser.expect.section('@main').to.not.be.present;\n    browser.expect.section('@main').to.be.present.before(100);\n  });\n\n  it('have .visible', () => {\n    browser.expect.section('@main').to.be.visible;\n    browser.expect.section('@main').to.not.be.visible;\n    browser.expect.section('@main').to.be.visible.before(100);\n  });\n});\n\ndescribe('expect.elements()', () => {\n  it('description', () => {\n    browser.expect.elements('div').count.to.equal(10);\n    browser.expect.elements('p').count.to.not.equal(1);\n\n    expectError(browser.expect.elements('div').value.contain('nightwatch'))\n  });\n\n  it('selector element properties - all & required', () => {\n    browser.expect\n      .elements({\n        selector: 'div',\n        locateStrategy: 'css selector',\n        index: 0,\n        timeout: 3000,\n        retryInterval: 1000,\n        suppressNotFoundErrors: false,\n        abortOnFailure: true,\n      })\n      .count.to.equal(10);\n    browser.expect\n      .elements({\n        selector: 'div',\n      })\n      .count.to.not.equal(1);\n  });\n});\n\nit('expect.title()', () => {\n  browser.expect.title().to.contain('value');\n  browser.expect.title().to.match(/value/);\n});\n\nit('expect.url()', () => {\n  browser.expect.url().to.equal('https://nightwatch.org');\n  browser.expect.url().to.contain('https://');\n  browser.expect.url().to.endWith('.org');\n});\n\nit('chains expect assertions', () => {\n  browser\n    .navigateTo('https://duckduckgo.com')\n    .expect.element('input[name=q]')\n    .with.attribute('placeholder')\n    .toContain('Search')\n    .expect.elements('input')\n    .count.toEqual(4)\n    .assert.titleContains('Privacy')\n    .url('https://google.com');\n\n  const result = browser.expect.elements('div').count.toEqual(4);\n  expectType<NightwatchAPI>(result);\n\n  expectNotAssignable<PromiseLike<any>>(result);\n});\n\nit('works with async/await', async () => {\n  const result = await browser.expect.element('#main').text.to.equal('The Night Watch');\n  expectType<NightwatchExpectResult>(result);\n  expectType<null>(result.value);\n});\n"
  },
  {
    "path": "types/tests/globalElementApi.test-d.ts",
    "content": "import { expectAssignable, expectError, expectType } from \"tsd\";\nimport { ElementGlobal, NightwatchAPI, NightwatchCallbackResult, NightwatchSizeAndPosition } from \"..\";\nimport { WebElement } from \"selenium-webdriver\";\n\ndescribe('global element() api', function () {\n  it('test element()', async function() {\n    // string as locator\n    const elem = element('selector');\n    expectType<ElementGlobal>(elem);\n    expectType<WebElement>(await elem.getWebElement());\n\n    // WebElement as selector\n    expectType<ElementGlobal>(element(await elem.getWebElement()));\n\n    // By as selector\n    expectType<ElementGlobal>(element(by.css('selector')));\n\n    // ElementProperties as selector\n    expectType<ElementGlobal>(element({selector: 'selector', index: 4}));\n\n    // with options\n    expectType<ElementGlobal>(element('selector', {isComponent: true, type: 'vue'}));\n  });\n\n\n  it('test element() methods and properties', async function() {\n    // string as locator\n    const elem = element('selector');\n    expectType<ElementGlobal>(elem);\n\n    // .getId()\n    expectAssignable<NightwatchAPI>(elem.getId(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    }));\n    expectType<string>(await elem.getId());\n\n    // .findElement()\n    expectAssignable<NightwatchAPI>(elem.findElement());\n    expectType<WebElement>(await elem.findElement());\n\n    expectAssignable<NightwatchAPI>(elem.findElement('child-selector', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<WebElement>>(result);\n    }));\n    expectType<WebElement>(await elem.findElement('child-selector'));\n\n    // .find()\n    expectAssignable<NightwatchAPI>(elem.find());\n    expectType<WebElement>(await elem.find());\n\n    expectAssignable<NightwatchAPI>(elem.find('child-selector', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<ElementGlobal | null>>(result);\n    }));\n    expectType<ElementGlobal | null>(await elem.find('child-selector'));\n\n    elem.find({using: 'css selector', value: 'child-selector'});\n    expectError(elem.find({value: 'child-selector'}));\n    expectError(elem.find({using: 'css selector', value: 'child-selector', abortOnFailure: true}));\n\n    const elemProp = {locateStrategy: 'css selector', selector: 'child-selector', abortOnFailure: true};\n    elem.find(elemProp);\n    expectError(elem.find({locateStrategy: 'css selector', selector: 'child-selector', abortOnFailure: true}));\n\n    expectError(elem.find({locateStrategy: 'css selector', value: 'child-selector'}));\n\n    // .get()\n    expectAssignable<NightwatchAPI>(elem.get());\n    expectType<WebElement>(await elem.get());\n    expectType<WebElement>(await elem.element());\n\n    expectAssignable<NightwatchAPI>(elem.get('child-selector', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<ElementGlobal | null>>(result);\n    }));\n    expectType<ElementGlobal | null>(await elem.get('child-selector'));\n    expectType<ElementGlobal | null>(await elem.element('child-selector'));\n\n    // .findElements()\n    expectAssignable<NightwatchAPI>(elem.findElements('child-selector', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<WebElement[]>>(result);\n    }));\n    expectType<WebElement[]>(await elem.findElements('child-selector'));\n\n    // .findAll()\n    expectAssignable<NightwatchAPI>(elem.findAll('child-selector', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<ElementGlobal[]>>(result);\n    }));\n    expectType<ElementGlobal[]>(await elem.findAll('child-selector'));\n\n    // .clear()\n    expectAssignable<NightwatchAPI>(elem.clear(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    }));\n    expectType<null>(await elem.clear())\n\n    // .click()\n    expectAssignable<NightwatchAPI>(elem.click(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    }));\n    expectType<null>(await elem.click());\n\n    // .getAccessibleName()\n    expectAssignable<NightwatchAPI>(elem.getAccessibleName(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    }));\n    expectType<string>(await elem.getAccessibleName());\n    expectType<string>(await elem.accessibleName());\n\n    // .getAriaRole()\n    expectAssignable<NightwatchAPI>(elem.getAriaRole(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    }));\n    expectType<string>(await elem.getAriaRole());\n    expectType<string>(await elem.ariaRole());\n\n    // .getAttribute()\n    expectAssignable<NightwatchAPI>(elem.getAttribute('attribute-name', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string | null>>(result);\n    }));\n    expectType<string | null>(await elem.getAttribute('attribute-name'));\n    expectType<string | null>(await elem.attr('attribute-name'));\n    expectType<string | null>(await elem.attribute('attribute-name'));\n\n    // .getCssValue()\n    expectAssignable<NightwatchAPI>(elem.getCssValue('prop-name', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    }));\n    expectType<string>(await elem.getCssValue('prop-name'));\n    expectType<string>(await elem.css('prop-name'));\n\n    // .getProperty()\n    expectAssignable<NightwatchAPI>(elem.getProperty('prop-name', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string | null>>(result);\n    }));\n    expectType<string | null>(await elem.getProperty('prop-name'));\n    expectType<string | null>(await elem.property('prop-name'));\n    expectType<string | null>(await elem.prop('prop-name'));\n\n    // .getRect()\n    expectAssignable<NightwatchAPI>(elem.getRect(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<NightwatchSizeAndPosition>>(result);\n    }));\n    expectType<NightwatchSizeAndPosition>(await elem.getRect());\n    expectType<NightwatchSizeAndPosition>(await elem.rect());\n\n    // .getTagName()\n    expectAssignable<NightwatchAPI>(elem.getTagName(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    }));\n    expectType<string>(await elem.getTagName());\n    expectType<string>(await elem.tagName());\n\n    // .getText()\n    expectAssignable<NightwatchAPI>(elem.getText(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    }));\n    expectType<string>(await elem.getText());\n    expectType<string>(await elem.text());\n\n    // .sendKeys()\n    expectAssignable<NightwatchAPI>(elem.sendKeys(1, 'something', browser.Keys.SPACE, Promise.resolve(2)));\n    expectType<null>(await elem.sendKeys());\n\n    // .submit()\n    expectAssignable<NightwatchAPI>(elem.submit(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    }));\n    expectType<null>(await elem.submit());\n\n    // .takeScreenshot()\n    expectAssignable<NightwatchAPI>(elem.takeScreenshot(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    }));\n    expectType<string>(await elem.takeScreenshot());\n    expectType<string>(await elem.screenshot());\n\n    // .isDisplayed()\n    expectAssignable<NightwatchAPI>(elem.isDisplayed(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<boolean>>(result);\n    }));\n    expectType<boolean>(await elem.isDisplayed());\n\n    // .isEnabled()\n    expectAssignable<NightwatchAPI>(elem.isEnabled(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<boolean>>(result);\n    }));\n    expectType<boolean>(await elem.isEnabled());\n\n    // .isSelected()\n    expectAssignable<NightwatchAPI>(elem.isSelected(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<boolean>>(result);\n    }));\n    expectType<boolean>(await elem.isSelected());\n\n    // .getWebElement()\n    expectAssignable<NightwatchAPI>(elem.getWebElement());\n    expectType<WebElement>(await elem.getWebElement());\n\n    // .isComponent\n    expectType<boolean>(elem.isComponent!);\n  });\n});\n"
  },
  {
    "path": "types/tests/index.test-d.ts",
    "content": "import { expectAssignable, expectError, expectNotType, expectType } from 'tsd';\nimport { EventEmitter } from 'events';\nimport {\n  EnhancedPageObject,\n  EnhancedSectionInstance,\n  NightwatchAPI,\n  NightwatchAssertion,\n  NightwatchAssertionsResult,\n  NightwatchBrowser,\n  NightwatchClient,\n  NightwatchClientObject,\n  NightwatchEnsureResult,\n  NightwatchNodeAssertionsResult,\n  NightwatchTests,\n  PageObjectModel,\n  ELEMENT_KEY,\n  JSON_WEB_OBJECT,\n  ElementResult,\n  Awaitable,\n  SectionProperties,\n  ScopedElement,\n  LocateStrategy\n} from '..';\nimport { element as elementNamedExport } from '..';\nimport { WebElement } from 'selenium-webdriver';\n\nfunction isNightwatchAssertionsResult<T>(result: NightwatchAssertionsResult<T>): T {\n  return result.value;\n}\n\n//\n// ./tests/general.ts\n//\n\nconst testGeneral: NightwatchTests = {\n  'Demo test Google 1': () => {\n    browser.registerBasicAuth('test-username', 'test-password').navigateTo('https://google.com').pause(1000);\n\n    // check types on browser.options\n    expectType<string | string[] | undefined>(browser.options.tag_filter);\n    // expect element <body> to be present in 1000ms\n    browser.expect.element('body').to.be.present.before(1000);\n\n    // expect element <#lst-ib> to have css property 'display'\n    browser.expect.element('#lst-ib').to.have.css('display');\n\n    // expect element <body> to have attribute 'class' which contains text 'vasq'\n    browser.expect.element('body').to.have.attribute('class').which.contains('vasq');\n\n    browser.expect.element('#hplogo').to.have.attribute('alt').which.startsWith('G').and.endsWith('oogle');\n\n    // expect element <#lst-ib> to be an input tag\n    browser.expect.element('#lst-ib').to.be.an('input');\n\n    // expect element <#lst-ib> to be visible\n    browser.expect.element('#lst-ib').to.be.visible;\n\n    browser.end();\n  },\n\n  'Demo test Google 2': () => {\n    browser\n      .url('https://www.google.com')\n      .waitForElementVisible('body')\n      .setValue('input[type=text]', 'nightwatch')\n      .getElementRect('input[type=text]', (res) => {\n        console.log(res.value);\n      })\n      .waitForElementVisible('input[name=btnK]')\n      .click('input[name=btnK]')\n      .pause(1000)\n      .assert.containsText('#main', 'Night Watch')\n      .end();\n  },\n\n  'Demo Nightwatch API commands': () => {\n    expectType<boolean>(browser.isChrome());\n    expectType<boolean>(browser.isAndroid());\n    expectType<boolean>(browser.isMobile());\n    expectType<boolean>(browser.isAppiumClient());\n\n    const element_id = browser.WEBDRIVER_ELEMENT_ID;\n    console.log(element_id);\n    const browserName = browser.browserName;\n    console.log(browserName);\n    expectError(() => {\n      browser.WEBDRIVER_ELEMENT_ID = 'some-element-id';\n    })\n\n    expectError(() => {\n      browser.browserName = 'firefox';\n    })\n\n    expectError(browser.element('css selector', 'something', function (result) {\n      if (result.status === 0) {\n        console.log(result.value);\n      }\n    }));\n\n    browser.elements('css selector', 'something', function (result) {\n      if (result.status === 0) {\n        expectType<string>(result.value[0][ELEMENT_KEY]);\n      }\n      expectType<NightwatchAPI>(this);\n    });\n  },\n\n  'Demo Nightwatch API commands with async/await': async () => {\n    // backward compatibility to some extent\n    const element = await browser.element('css selector', 'something');\n    expectType<WebElement>(element);\n\n    const elements = await browser.elements('css selector', 'something');\n    expectType<string>(elements[0][ELEMENT_KEY]);\n\n    // new element api\n    const elem = elementNamedExport('selector');\n    expectType<ScopedElement>(elem);\n    expectType<WebElement>(await elem);\n\n    const childChildEle = await elementNamedExport.find('selector').findAll('child-selector').nth(2).find('child-child-selector');\n    expectType<WebElement>(childChildEle);\n  },\n\n  'Can run accessibility tests': () => {\n    browser\n      .url('https://nightwatchjs.org')\n      .axeInject()\n      .axeRun(['#navBar', 'nav'], {\n        rules: {\n          'color-contrast': { enabled: false },\n          region: { enabled: false }\n        },\n      }, (result) => {\n        if (result.status === 0) {\n          expectType<{[key: string]: any}>(result.value);\n        }\n      });\n  },\n\n  'step one: navigate to google': () => {\n    browser\n      .url('https://www.google.com')\n      .waitForElementVisible('body', 1000)\n      .setValue('input[type=text]', 'nightwatch')\n      .waitForElementVisible('input[name=btnK]', 1000);\n  },\n\n  'step two: click input': () => {\n    browser.click('input[name=btnK]').pause(1000).assert.containsText('#main', 'Night Watch').end();\n  },\n\n  'test user defined globals': () => {\n    browser.url(`http://${browser.globals.username}:${browser.globals.password}@example.com`).end();\n  },\n\n  'Demo test for built-in API commands for working with the Chrome Devtools Protocol': () => {\n    // setGeolocation\n    browser\n      // Set location of Tokyo, Japan\n      .setGeolocation({\n        latitude: 35.689487,\n        longitude: 139.691706,\n        accuracy: 100,\n      })\n      .captureNetworkRequests((requestParams) => {\n        console.log('Request URL:', requestParams.request.url);\n        console.log('Request method:', requestParams.request.method);\n        console.log('Request headers:', requestParams.request.headers);\n      })\n      .navigateTo('https://www.gps-coordinates.net/my-location')\n      .end();\n\n    browser\n      .mockNetworkResponse(\n        'https://www.google.com/',\n        {\n          status: 200,\n          headers: {\n            'Content-Type': 'UTF-8',\n          },\n          body: 'Hello there!',\n        },\n        (res) => {\n          console.log(res);\n        }\n      )\n      .setDeviceDimensions({\n        width: 400,\n        height: 600,\n        deviceScaleFactor: 50,\n        mobile: true,\n      })\n      .navigateTo('https://www.google.com')\n      .end();\n\n    browser\n      .enablePerformanceMetrics()\n      .navigateTo('https://www.google.com')\n      .getPerformanceMetrics((metrics) => {\n        console.log(metrics);\n      });\n\n    browser.navigateTo('https://www.google.com').takeHeapSnapshot('./snap.heapsnapshot').end();\n\n    browser\n      .captureBrowserConsoleLogs((event) => {\n        console.log(event.type, event.timestamp, event.args[0].value);\n      })\n      .navigateTo(browser.baseUrl)\n      .executeScript(() => {\n        console.error('here');\n      }, []);\n  },\n  'test assert with async/await': async () => {\n    const attributeResult = browser.assert.attributeContains('input[name=q]', 'placeholder', 'Search');\n    expectType<Awaitable<NightwatchAPI, NightwatchAssertionsResult<string>>>(attributeResult);\n    isNightwatchAssertionsResult<string>(await attributeResult);\n\n    const cssPropertyResult = browser.assert.cssProperty('input[name=q]', 'classList', 'searchbox');\n    expectType<Awaitable<NightwatchAPI, NightwatchAssertionsResult<string>>>(cssPropertyResult);\n    isNightwatchAssertionsResult<string | number>(await cssPropertyResult);\n\n    const domPropertyResult = browser.assert.domPropertyContains('input[name=q]', 'classList', 'searchbox');\n    expectType<Awaitable<NightwatchAPI, NightwatchAssertionsResult<any>>>(domPropertyResult);\n    isNightwatchAssertionsResult<any>(await domPropertyResult);\n\n    const elementsCountResult = browser.assert.elementsCount('input', 8);\n    expectType<\n      Awaitable<\n        NightwatchAPI,\n        NightwatchAssertionsResult<JSON_WEB_OBJECT[]> & {\n          WebdriverElementId: string;\n        }\n      >\n    >(elementsCountResult);\n    const elementsCountAwaitedResult = await elementsCountResult;\n    expectType<JSON_WEB_OBJECT[]>(elementsCountAwaitedResult.value);\n    expectType<string>(elementsCountAwaitedResult.WebdriverElementId);\n\n    const elementPresentResult = browser.assert.elementPresent('input');\n    expectType<Awaitable<NightwatchAPI, NightwatchAssertionsResult<ElementResult[]>>>(elementPresentResult);\n    isNightwatchAssertionsResult<Array<{ [ELEMENT_KEY]: string }>>(await elementPresentResult);\n\n    const hasAttributeResult = browser.assert.hasAttribute('input[name=q]', 'placeholder');\n    expectType<Awaitable<NightwatchAPI, NightwatchAssertionsResult<string>>>(hasAttributeResult);\n    isNightwatchAssertionsResult<string>(await hasAttributeResult);\n\n    const selectedResult = browser.assert.selected('input[name=q]');\n    expectType<Awaitable<NightwatchAPI, NightwatchAssertionsResult<boolean>>>(selectedResult);\n    isNightwatchAssertionsResult<boolean>(await selectedResult);\n\n    const textResult = browser.assert.textMatches('input[name=q]', /^Search/);\n    expectType<Awaitable<NightwatchAPI, NightwatchAssertionsResult<string>>>(textResult);\n    isNightwatchAssertionsResult<string>(await textResult);\n\n    const urlResult = browser.assert.urlMatches('https://nightwatch.org');\n    expectType<Awaitable<NightwatchAPI, NightwatchAssertionsResult<string>>>(urlResult);\n    isNightwatchAssertionsResult<string>(await urlResult);\n  },\n  'test node assertions with async/await': async () => {\n    const result = browser.assert.strictEqual('nightwatch', 'nightwatch');\n    expectType<Awaitable<NightwatchAPI, Error | NightwatchNodeAssertionsResult>>(result);\n    expectType<NightwatchNodeAssertionsResult | Error>(await result);\n  },\n};\n\n//\n// ./tests/duckDuckGo.ts\n//\ndescribe('duckduckgo example', function () {\n  it('Search Nightwatch.js and check results', function (browser) {\n    browser\n      .navigateTo('https://duckduckgo.com')\n      .waitForElementVisible('input[name=q]')\n      .sendKeys('input[name=q]', ['Nightwatch.js'])\n      .click('*[type=\"submit\"]')\n      .assert.visible('.results--main')\n      .assert.textContains('.results--main', 'Nightwatch.js');\n  });\n});\n\n//\n// .tests/native/wikipedia.ts\n//\nconst wikipediaAppTest: NightwatchTests = {\n  before: (client: NightwatchBrowser) => {\n    client.click(by.xpath('//XCUIElementTypeButton[@name=\"Skip\"]'));\n  },\n\n  after: (client: NightwatchAPI) => {\n    client.end();\n  },\n\n  'Search for BrowserStack': async (client: NightwatchAPI) => {\n    client\n      .useXpath()\n      .click('//XCUIElementTypeSearchField[@name=\"Search Wikipedia\"]')\n      .getOrientation(function (result) {\n        if (result.status === 0) {\n          expectType<'LANDSCAPE' | 'PORTRAIT'>(result.value);\n        }\n        expectType<NightwatchAPI>(this);\n      })\n      .setOrientation('LANDSCAPE', function (result) {\n        if (result.status === 0) {\n          expectType<'LANDSCAPE' | 'PORTRAIT'>(result.value);\n        }\n        expectType<NightwatchAPI>(this);\n      })\n      .appium.pressKeyCode(13, 44)\n      .sendKeys('//XCUIElementTypeSearchField[@name=\"Search Wikipedia\"]', 'browserstack')\n      .click('//XCUIElementTypeStaticText[@name=\"BrowserStack\"]')\n      .waitUntil(async function () {\n        // wait for webview context to be available\n        const contexts = await this.appium.getContexts(function (result) {\n          if (result.status === 0) {\n            expectType<string[]>(result.value);\n          }\n          expectType<NightwatchAPI>(this);\n        });\n\n        return contexts.length > 1;\n      }, 50000)\n      .perform(async function () {\n        // switch to webview context\n        const contexts = await this.contexts();\n        const setContextResult = await this.setContext(contexts[1], function (result) {\n          if (result.status === 0) {\n            expectType<null>(result.value);\n          }\n          expectType<NightwatchAPI>(this);\n        });\n\n        const currContext = await this.currentContext(function (result) {\n          if (result.status === 0) {\n            expectType<string | null>(result.value);\n          }\n          expectType<NightwatchAPI>(this);\n        });\n\n        expectType<string[]>(contexts);\n        expectType<null>(setContextResult);\n        expectType<string | null>(currContext);\n\n        // switch orientation back to portrait\n        const currOrientation = await client.getOrientation();\n        const setOrientationResult = await client.setOrientation('PORTRAIT');\n\n        expectType<'LANDSCAPE' | 'PORTRAIT'>(currOrientation);\n        expectType<'LANDSCAPE' | 'PORTRAIT'>(setOrientationResult);\n      })\n      .useCss()\n      .assert.textEquals('.pcs-edit-section-title', 'BrowserStack'); // command run in webview context\n  },\n};\n\n//\n// ./pages/google.ts\n//\n\nconst appsSection = {\n  selector: 'div.gb_qc',\n  commands: {\n    clickYoutube(this: EnhancedSectionInstance) {\n      return this.click('@youtube');\n    },\n    something(this: EnhancedSectionInstance) {\n      return this.click('@youtube');\n    },\n  },\n  elements: [{\n    myAccount: '#gb192'\n  },\n  {\n    youtube: {\n      selector: '#gb36',\n    },\n  }]\n} satisfies SectionProperties;\n\nconst menuSection = {\n  selector: '#gb',\n  locateStrategy: 'css selector',\n  commands: [\n    {\n      // add section commands here\n      clickApps(this: EnhancedSectionInstance) {\n        return this.click('@appSection');\n      },\n\n      randomCommand(this: EnhancedSectionInstance) {\n        return this.click('@appSection');\n      },\n    },\n    {\n      doSomething(this: EnhancedSectionInstance) {\n        return this.click('@appSection');\n      },\n    },\n  ],\n  elements: {\n    mail: 'a[href=\"mail\"]',\n    images: {\n      selector: 'a[href=\"imghp\"]',\n    },\n  },\n  sections: {\n    apps: appsSection,\n  },\n} satisfies SectionProperties;\n\nconst googleCommands = {\n  submit(this: GooglePage) {\n    this.api.pause(1000);\n    return this.waitForElementVisible('@submitButton', 1000)\n      .click('@submitButton')\n      .waitForElementNotPresent('@submitButton');\n  },\n};\n\nconst googlePage = {\n  commands: [googleCommands],\n  elements: {\n    searchBar: 'input[type=text]',\n    submitButton: {\n      selector: 'input[name=btnK]',\n      locateStrategy: 'css selector'\n    },\n  },\n  sections: {\n    menu: menuSection,\n  },\n} satisfies PageObjectModel;\n\n// export = googlePage;\n\n// const iFrameCommands = {\n//   url(this: EnhancedPageObject) {\n//     return `${this.api.launch_url}/iframe`;\n//   },\n// }\n\nconst iFrame = {\n  elements: [{\n    iframe: '#mce_0_ifr',\n    hey: undefined\n  },\n  {\n    textbox: {\n      selector: 'body#tinymce p',\n    }\n  }],\n  commands: {\n    url(this: EnhancedPageObject) {\n      return `${this.api.launch_url}/iframe`;\n    },\n  },\n} satisfies PageObjectModel;\n\n// export = iFrame\n\ninterface GooglePage\n  extends EnhancedPageObject<\n    typeof googleCommands,\n    typeof googlePage.elements,\n    typeof googlePage.sections\n  > {}\n\ninterface iFramePage extends EnhancedPageObject<typeof iFrame.commands, typeof iFrame.elements> {}\n\ndeclare module '..' {\n  interface NightwatchCustomPageObjects {\n    google(): GooglePage;\n    IFrame(): iFramePage;\n  }\n}\n\n// TODO: fix Page Object types\nconst testPage = {\n  'Test commands': () => {\n    const google = browser.page.google();\n    google.setValue('@searchBar', 'nightwatch').submit().assert.titleContains('nightwatch');\n\n    expectType<NightwatchAPI>(google.api);\n    expectType<NightwatchClient>(google.client);\n\n    const result = google\n      .setValue('@searchBar', 'nightwatch')\n      .assert.titleContains('Google');\n    \n    expectAssignable<GooglePage>(result);\n    expectAssignable<GooglePage>(result.submit());\n    expectAssignable<GooglePage>(result.cookies.getAll());\n\n    // test new element api\n    google.element('@searchBar');\n    google.element.findAll('@searchBar');\n\n    browser.end();\n  },\n\n  'Test sections': () => {\n    const google = browser.page.google();\n\n    expectAssignable<GooglePage>(google.cookies.deleteAll());\n    expectError(googlePage.window.maximize());\n\n    const menuSection = google.section.menu;\n\n    expectType<string>(menuSection.selector);\n    expectType<LocateStrategy>(menuSection.locateStrategy);\n\n    google.expect.section('@menu').to.be.visible;\n    google.expect.section(menuSection).to.be.visible;\n\n    const result = menuSection\n      .assert.visible('@mail')\n      .assert.visible('@images');\n\n    expectAssignable<typeof menuSection>(result);\n\n    menuSection.expect.element('@mail').to.be.visible;\n    menuSection.expect.element('@images').to.be.visible;\n\n    expectAssignable<typeof menuSection>(menuSection.alerts.accept());\n    expectType<NightwatchAPI>(menuSection.api);\n    expectType<NightwatchClient>(menuSection.client);\n\n    menuSection.selector;\n\n    expectNotType<any>(menuSection.clickApps());\n\n    const imagesElement = menuSection.elements.images;\n    expectNotType<any>(imagesElement);\n\n    const appSection = menuSection.section.apps;\n    appSection.expect.element('@myAccount').to.be.visible;\n    appSection.expect.element('@youtube').to.be.visible;\n\n    // test for parent property\n    expectType<typeof menuSection>(appSection.parent);\n    expectType<GooglePage>(appSection.parent.parent);\n    expectError(appSection.parent.parent.parent);\n\n    const youtubeElement = appSection.elements.youtube;\n    expectNotType<any>(youtubeElement);\n\n    // test new element api\n    menuSection.element('@main');\n    menuSection.element.findAll('@main').nth(1).find('@images');\n\n    expectNotType<any>(appSection.clickYoutube());\n\n    browser.end();\n  },\n\n  'Test assertions on page': () => {\n    const google: GooglePage = browser.page.google();\n\n    google\n      .navigate()\n      .assert.title('Google') // deprecated\n      .assert.titleEquals('Google') // new in 2.0\n      .assert.visible('@searchBar')\n      .assert.strictEqual('Google', 'Google') // node assertion returning NightwatchAPI\n      .assert.not.titleContains('DuckDuckGo')\n      .moveToElement('@searchBar', 1, 1)\n      .setValue('@searchBar', 'nightwatch')\n      .click('@submit');\n\n    expectError(google.assert.not.not.elementPresent('@searchbar'))\n    expectError(google.assert.not.strictEqual('nightwatch', 'nightwatch'))\n\n    browser.end();\n  },\n\n  'Test iFrame on page': async () => {\n    const iFrame = browser.page.IFrame();\n    iFrame.navigate();\n    const frame = await browser.findElement(iFrame.elements.iframe);\n    console.log(frame.getId());\n    browser.frame(frame.getId());\n    iFrame.expect.element('@textbox').text.to.equal('Your content goes here.');\n\n    browser.end();\n  },\n\n  'Test passing CSS selector string to frame': () => {\n    const iFrame = browser.page.IFrame();\n    iFrame.navigate().waitForElementPresent('#mce_0_ifr', 10000);\n    browser.frame('#mce_0_ifr');\n    iFrame.expect.element('@textbox').text.to.equal('Your content goes here.');\n    browser.end();\n  },\n\n  'Test nested page objects': () => {\n    const google = browser.page.subfolder1.subfolder2.subfolder3.google();\n  },\n};\n\n//\n// ./tests/specific-commands.ts\n//\n\nconst testSpecificCommands: NightwatchTests = {\n  executeAsync: () => {\n    browser.executeAsync(\n      (done) => {\n        setTimeout(() => {\n          done(true);\n        }, 500);\n      },\n      [],\n      (result) => {\n        browser.assert.equal(result.value, true);\n      }\n    );\n\n    browser.executeAsync(\n      (arg1: number, arg2: string, done: (result: true) => void) => {\n        setTimeout(() => {\n          done(true);\n        }, 500);\n      },\n      [1, '2'],\n      (result) => {\n        browser.assert.equal(result.value, true);\n      }\n    );\n\n    browser.end();\n  },\n\n  executeAsyncScript: () => {\n    browser.executeAsyncScript(\n      (done) => {\n        setTimeout(() => {\n          done(true);\n        }, 500);\n      },\n      [],\n      (result) => {\n        browser.assert.equal(result.value, true);\n      }\n    );\n\n    browser.executeAsyncScript(\n      (arg1: number, arg2: number, done: (result: boolean) => void) => {\n        setTimeout(() => {\n          done(true);\n        }, 500);\n      },\n      [1, 2],\n      (result) => {\n        browser.assert.equal(result.value, true);\n      }\n    );\n\n    browser.end();\n  },\n};\n\n//\n// ./commands/localStorageValue.ts\n// - function based command\n//\n\nfunction localStorageValueCommand(this: NightwatchAPI, key: string, callback?: (value: string | null) => void) {\n  const self = this;\n\n  this.execute(\n    // tslint:disable-next-line:only-arrow-functions\n    function (key) {\n      return window.localStorage.getItem(key);\n    },\n    [key], // arguments array to be passed\n    (result) => {\n      if (result.status) {\n        throw result.value;\n      }\n      if (typeof callback === 'function') {\n        callback.call(self, result.value);\n      }\n    }\n  );\n\n  return this;\n}\n\ndeclare module '..' {\n  interface NightwatchCustomCommands {\n    localStorageValue(key: string, callback?: (value: string | null) => void): this;\n  }\n}\n\n// module.exports.command = resizeCommand;\n\nconst testCustomCommandFunction = {\n  'Test command function': () => {\n    browser.localStorageValue('my-key', (result) => {\n      console.log(result);\n    });\n  },\n};\n\n//\n// ./commands/consoleLog.ts\n// - class based command\n//\n\nclass ConsoleLog extends EventEmitter {\n  command(this: ConsoleLog & NightwatchAPI, message: string, ...args: any[]) {\n    setTimeout(() => {\n      console.log(message, ...args);\n      this.emit('complete');\n    }, 1);\n\n    return this;\n  }\n}\n\ndeclare module '..' {\n  interface NightwatchCustomCommands {\n    consoleLog(message: string, ...args: any[]): this;\n  }\n}\n\n// module.exports = ConsoleLog;\n\nconst testCustomCommandClass = {\n  'Test command class': () => {\n    browser.consoleLog('Hello world!');\n  },\n};\n\n//\n// ./assertions/text.ts\n//\n\nfunction text(this: NightwatchAssertion<string>, selector: string, expectedText: string, msg?: string) {\n  this.expected = expectedText;\n\n  this.message = msg || `Element <${selector}> has text ${this.expected}.`;\n\n  this.pass = (value) => value === expectedText;\n\n  this.value = (result) => result.value!;\n\n  this.command = function (callback) {\n    this.api.findElement('css selector', selector, (elementResult) => {\n      if (elementResult.status === 0) {\n        this.api.elementIdText(elementResult.value[ELEMENT_KEY as keyof ElementResult], (textResult) => {\n          callback({ value: textResult.value as string });\n        });\n      }\n    });\n    return this;\n  };\n\n  expectType<NightwatchClientObject>(this.client);\n}\n\n// exports.assertion = text;\n\ndeclare module '..' {\n  interface NightwatchCustomAssertions<ReturnType> {\n    text: (selector: string, expectedText: string, msg?: string) => NightwatchAPI;\n  }\n}\n\nconst testCustomAssertion = {\n  'Test custom assertion': () => {\n    browser.assert.text('#checkme', 'Exactly match text');\n  },\n};\n\n// test global element\n\ndescribe('demo element() global', () => {\n  const signupEl = element(by.css('#signupSection'));\n  const loginEl = element('#weblogin');\n\n  test('element globals command', async () => {\n    // use elements created with element() to regular nightwatch assertions\n    browser.assert.visible(loginEl);\n\n    // use elements created with element() to expect assertions\n    browser.expect.element(loginEl).to.be.visible;\n\n    // retrieve the WebElement instance\n    const loginWebElement = await loginEl.getWebElement();\n  });\n});\n\n// Ensure test\n\nit('Ensure demo test', () => {\n  browser\n    .url('https://nightwatchjs.org')\n    .ensure.titleMatches(/Nightwatch.js/)\n    .ensure.elementIsVisible('#index-container');\n});\n\nit('Ensure async/await demo test', async () => {\n  const result = await browser\n    .url('https://nightwatchjs.org')\n    .ensure.urlContains('nightwatch')\n    .ensure.titleMatches(/Nightwatch.js/)\n    .ensure.elementIsVisible('#index-container');\n\n  function isNightwatchEnsureResult(v: NightwatchEnsureResult) {}\n  function isNull(v: null) {}\n\n  isNightwatchEnsureResult(result);\n  isNull(result.value);\n});\n\n// chai expect test\n\nit('Chai demo test', () => {\n  const infoElement = element('.info');\n  expect(infoElement.property('innerHTML')).to.be.a('string').and.to.include('validation code');\n});\n\n// Relative locator test\n// Describe not working\ndescribe('sample with relative locators', () => {\n  before((browser) => browser.navigateTo('https://archive.org/account/login'));\n\n  it('locates password input', () => {\n    const passwordElement = locateWith(By.tagName('input')).below(By.css('input[type=email]'));\n\n    browser.waitForElementVisible(passwordElement).expect.element(passwordElement).to.be.an('input');\n\n    browser.expect.element(passwordElement).attribute('type').equal('password');\n  });\n});\n"
  },
  {
    "path": "types/tests/namespaceCommands.test-d.ts",
    "content": "import { expectAssignable, expectType } from 'tsd';\nimport { NightwatchAPI, NightwatchLogEntry, NightwatchLogTypes } from '..';\n\n\n//\n// .logs.getSessionLog\n//\ndescribe('get log from Selenium', function() {\n  it('get browser log (default)', function(browser) {\n    const result = browser.logs.getSessionLog(function(result) {\n      expectType<NightwatchAPI>(this);\n      if (result.status === 0) {\n        const logEntriesArray = result.value;\n        expectType<NightwatchLogEntry[]>(logEntriesArray);\n      }\n    });\n    expectAssignable<NightwatchAPI>(result);\n\n    browser.logs.getSessionLog('client', function(result) {\n      expectType<NightwatchAPI>(this);\n      if (result.status === 0) {\n        const logEntriesArray = result.value;\n        expectType<NightwatchLogEntry[]>(logEntriesArray);\n      }\n    });\n  });\n\n  it('get driver log with ES6 async/await', async function(browser) {\n    const driverLogAvailable = await browser.logs.isSessionLogAvailable('driver');\n    expectType<boolean>(driverLogAvailable);\n\n    if (driverLogAvailable) {\n      const logEntriesArray = await browser.logs.getSessionLog('driver');\n      expectType<NightwatchLogEntry[]>(logEntriesArray);\n    }\n  });\n});\n\n//\n// .logs.getSessionLogTypes\n//\ndescribe('get available log types', function() {\n  it('get log types', function(browser) {\n    const result = browser.logs.getSessionLogTypes(function(result) {\n      expectType<NightwatchAPI>(this);\n      if (result.status === 0) {\n        const logTypes = result.value;\n        expectType<NightwatchLogTypes[]>(logTypes);\n      }\n    });\n    expectAssignable<NightwatchAPI>(result);\n  });\n\n  it('get log types with ES6 async/await', async function(browser) {\n    const logTypes = await browser.logs.getSessionLogTypes();\n    expectType<NightwatchLogTypes[]>(logTypes);\n  });\n});\n\n//\n// .logs.isSessionLogAvailable\n//\ndescribe('test if the log type is available', function() {\n  it('test browser log type', function(browser) {\n    const result = browser.logs.isSessionLogAvailable(function(result) {\n      expectType<NightwatchAPI>(this);\n      if (result.status === 0) {\n        const isAvailable = result.value;\n        expectType<boolean>(isAvailable);\n      }\n    });\n    expectAssignable<NightwatchAPI>(result);\n\n    browser.logs.isSessionLogAvailable('performance', function(result) {\n      expectType<NightwatchAPI>(this);\n      if (result.status === 0) {\n        const isAvailable = result.value;\n        expectType<boolean>(isAvailable);\n      }\n    });\n  });\n\n  it('test driver log type with ES6 async/await', async function(browser) {\n    const isAvailable = await browser.logs.isSessionLogAvailable('driver');\n    expectType<boolean>(isAvailable);\n    if (isAvailable) {\n      // do something more in here\n    }\n  });\n});\n"
  },
  {
    "path": "types/tests/page-object.test-d.ts",
    "content": "import {expectError, expectType} from 'tsd';\nimport {EnhancedPageObject, PageObjectModel, Awaitable, NightwatchAPI, Cookie, NightwatchLogEntry, NightwatchLogTypes, WindowSizeAndPosition} from '..';\nimport {WebElement} from 'selenium-webdriver';\n\n// Page object file\nconst fileUploadPageElements = {\n  fileUploadInput: 'input#file-upload',\n  submitButton: 'input#file-submit',\n  uploadFiles: '#uploaded-files'\n};\n\nconst menuSection = {\n  selector: 'nav',\n  elements: {\n    home: 'a[href=\"/\"]',\n    about: 'a[href=\"/about\"]'\n  }\n};\n\nconst fileUploadPage = {\n  url(this: EnhancedPageObject) {\n    return `${this.api.launch_url}/upload`;\n  },\n  elements: fileUploadPageElements,\n  sections: {\n    menu: menuSection\n  }\n} satisfies PageObjectModel;\n\nexport interface FileUploadPage extends\n  EnhancedPageObject<{}, typeof fileUploadPageElements, typeof fileUploadPage.sections, {}, () => string> {} // eslint-disable-line @typescript-eslint/ban-types\n\nexport default fileUploadPage;\n\n\n// Declare the newly created page object in the NightwatchCustomPageObjects interface.\n// This will allow you to access the page object type in your test files.\ndeclare module '..' {\n  interface NightwatchCustomPageObjects {\n    FileUpload(): FileUploadPage;\n  }\n  interface NightwatchCustomCommands {\n    // uploadFile1 returns NightwatchAPI (breaks chaining on page objects)\n    uploadFile1(selector: string, filePath: string): NightwatchAPI;\n    // uploadFile2 returns Awaitable<NightwatchAPI, null> (breaks chaining on page objects)\n    uploadFile2(selector: string, filePath: string): Awaitable<NightwatchAPI, null>;\n    // uploadFile3 returns 'this' (allows chaining)\n    uploadFile3(selector: string, filePath: string): this;\n    // uploadFile4 returns 'this' (allows chaining)\n    uploadFile4(selector: string, filePath: string): Awaitable<this, null>;\n    upload: {\n      file(selector: string, filePath: string): NightwatchAPI;\n    }\n  }\n}\n\n\n// test file\ndescribe('File Upload', function() {\n  it('File Upload test', function() {\n    const fileUploadPage = browser.page.FileUpload();\n    const url = fileUploadPage.url();\n\n    fileUploadPage\n      .navigate(url)\n      .uploadFile('@fileUploadInput', 'test.txt')\n      // alternate way of passing an element instead of '@submitButton'\n      .click(fileUploadPage.elements.submitButton)\n      .expect.element('@uploadFiles').text.to.equal('test.txt');\n\n    // test custom commands over page object\n    expectType<NightwatchAPI>(fileUploadPage.uploadFile1('@fileUploadInput', 'test2.txt'));\n    expectType<Awaitable<NightwatchAPI, null>>(fileUploadPage.uploadFile2('@fileUploadInput', 'test2.txt'));\n    // uploadFile3 returns 'this', so it preserves the page object type\n    expectType<FileUploadPage>(fileUploadPage.uploadFile3('@fileUploadInput', 'test2.txt'));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.uploadFile4('@fileUploadInput', 'test2.txt'));\n    // should fail ideally but succeeding (namespace from custom commands not loaded directly into page object??)\n    expectType<NightwatchAPI>(fileUploadPage.upload.file('@fileUploadInput', 'test2.txt'));\n\n    // test custom commands over page object sections\n    const menuSection = fileUploadPage.section.menu;\n    expectType<NightwatchAPI>(menuSection.uploadFile1('@fileUploadInput', 'test2.txt'));\n    expectType<Awaitable<NightwatchAPI, null>>(menuSection.uploadFile2('@fileUploadInput', 'test2.txt'));\n    // uploadFile3 returns 'this', so it preserves the section type\n    // Note: TypeScript may not properly resolve 'this' for custom commands on sections\n    // The command works, but type resolution is limited\n    menuSection.uploadFile3('@fileUploadInput', 'test2.txt');\n    // should fail because the namespaces from custom commands are not loaded directly into the section\n    expectError(menuSection.upload.file('@fileUploadInput', 'test2.txt'));\n\n    browser.end();\n  });\n});\n\n\n/**************************\n * OTHER TESTS\n *************************/\ndescribe('File Upload 2', function() {\n  it('File Upload test', function() {\n    const fileUploadPage = browser.page.FileUpload();\n\n    // user actions element commands work on page objects\n    fileUploadPage.rightClick('@fileUploadInput');\n    fileUploadPage.doubleClick('@fileUploadInput');\n    fileUploadPage.clickAndHold('@fileUploadInput');\n    expectError(fileUploadPage.navigateTo('https://google.com'));\n    expectType<string>(fileUploadPage.url());\n\n    // user actions element commands work on sections\n    const menuSection = fileUploadPage.section.menu;\n    menuSection.rightClick('@fileUploadInput');\n    menuSection.doubleClick('@fileUploadInput');\n    menuSection.clickAndHold('@fileUploadInput');\n    expectError(menuSection.navigateTo('https://google.com'));\n    expectError(menuSection.url());\n  });\n});\n\n/**************************\n * TESTS FOR MOVED COMMANDS (SharedClientCommands)\n *************************/\ndescribe('Page Object - SharedClientCommands', function() {\n  it('should have access to moved commands from SharedClientCommands', function() {\n    const fileUploadPage = browser.page.FileUpload();\n    const menuSection = fileUploadPage.section.menu;\n\n    // Test commands that were moved to SharedClientCommands\n    // Verify they exist, are callable, and return correct types\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.axeInject());\n    expectType<Awaitable<FileUploadPage, { [key: string]: any }>>(fileUploadPage.axeRun());\n    expectType<Awaitable<FileUploadPage, undefined>>(fileUploadPage.debug());\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.deleteCookie('test'));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.deleteCookies());\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.end());\n    expectType<Awaitable<FileUploadPage, Cookie>>(fileUploadPage.getCookie('test-cookie'));\n    expectType<Awaitable<FileUploadPage, Cookie[]>>(fileUploadPage.getCookies());\n    expectType<Awaitable<FileUploadPage, NightwatchLogEntry[]>>(fileUploadPage.getLog('server'));\n    expectType<Awaitable<FileUploadPage, NightwatchLogTypes[]>>(fileUploadPage.getLogTypes());\n    expectType<Awaitable<FileUploadPage, string>>(fileUploadPage.getTitle());\n    expectType<Awaitable<FileUploadPage, { x: number; y: number }>>(fileUploadPage.getWindowPosition());\n    expectType<Awaitable<FileUploadPage, WindowSizeAndPosition>>(fileUploadPage.getWindowRect());\n    expectType<Awaitable<FileUploadPage, WindowSizeAndPosition>>(fileUploadPage.getWindowSize());\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.init());\n    expectType<Awaitable<FileUploadPage, WebElement>>(fileUploadPage.injectScript('script.js'));\n    expectType<Awaitable<FileUploadPage, boolean>>(fileUploadPage.isLogAvailable('browser'));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.maximizeWindow());\n    expectType<Awaitable<FileUploadPage, string>>(fileUploadPage.pageSource());\n    expectType<Awaitable<FileUploadPage, undefined>>(fileUploadPage.pause(1000));\n    expectType<Awaitable<FileUploadPage, void>>(fileUploadPage.perform(() => {}));\n    expectType<Awaitable<FileUploadPage, string>>(fileUploadPage.perform<string>(() => {}));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.resizeWindow(1000, 800));\n    expectType<Awaitable<FileUploadPage, string>>(fileUploadPage.saveScreenshot('test.png'));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.setCookie({name: 'test', value: 'value'}));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.setWindowPosition(0, 0));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.setWindowRect({x: 0, y: 0, width: 800, height: 600}));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.setWindowSize(800, 600));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.urlHash('#test'));\n    expectType<Awaitable<FileUploadPage, undefined>>(fileUploadPage.useCss());\n    expectType<Awaitable<FileUploadPage, undefined>>(fileUploadPage.useXpath());\n\n    // These should also work on sections with correct return types\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.axeInject());\n    expectType<Awaitable<typeof menuSection, { [key: string]: any }>>(menuSection.axeRun());\n    expectType<Awaitable<typeof menuSection, undefined>>(menuSection.debug());\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.deleteCookie('test'));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.deleteCookies());\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.end());\n    expectType<Awaitable<typeof menuSection, Cookie>>(menuSection.getCookie('test-cookie'));\n    expectType<Awaitable<typeof menuSection, Cookie[]>>(menuSection.getCookies());\n    expectType<Awaitable<typeof menuSection, NightwatchLogEntry[]>>(menuSection.getLog('server'));\n    expectType<Awaitable<typeof menuSection, NightwatchLogTypes[]>>(menuSection.getLogTypes());\n    expectType<Awaitable<typeof menuSection, string>>(menuSection.getTitle());\n    expectType<Awaitable<typeof menuSection, { x: number; y: number }>>(menuSection.getWindowPosition());\n    expectType<Awaitable<typeof menuSection, WindowSizeAndPosition>>(menuSection.getWindowRect());\n    expectType<Awaitable<typeof menuSection, WindowSizeAndPosition>>(menuSection.getWindowSize());\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.init());\n    expectType<Awaitable<typeof menuSection, WebElement>>(menuSection.injectScript('script.js'));\n    expectType<Awaitable<typeof menuSection, boolean>>(menuSection.isLogAvailable('browser'));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.maximizeWindow());\n    expectType<Awaitable<typeof menuSection, string>>(menuSection.pageSource());\n    expectType<Awaitable<typeof menuSection, undefined>>(menuSection.pause(1000));\n    expectType<Awaitable<typeof menuSection, void>>(menuSection.perform(() => {}));\n    expectType<Awaitable<typeof menuSection, string>>(menuSection.perform<string>(() => {}));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.resizeWindow(1000, 800));\n    expectType<Awaitable<typeof menuSection, string>>(menuSection.saveScreenshot('test.png'));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.setCookie({name: 'test', value: 'value'}));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.setWindowPosition(0, 0));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.setWindowRect({x: 0, y: 0, width: 800, height: 600}));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.setWindowSize(800, 600));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.urlHash('#test'));\n    expectType<Awaitable<typeof menuSection, undefined>>(menuSection.useCss());\n    expectType<Awaitable<typeof menuSection, undefined>>(menuSection.useXpath());\n  });\n});\n\n/**************************\n * TESTS FOR CHROMIUM CLIENT COMMANDS\n *************************/\ndescribe('Page Object - ChromiumClientCommands', function() {\n  it('should have access to commands from ChromiumClientCommands', function() {\n    const fileUploadPage = browser.page.FileUpload();\n    const menuSection = fileUploadPage.section.menu;\n\n    // Test commands from ChromiumClientCommands\n    // Verify they exist, are callable, and return correct types\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.setGeolocation({latitude: 35.689487, longitude: 139.691706, accuracy: 100}));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.setGeolocation());\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.setDeviceDimensions({width: 400, height: 600, deviceScaleFactor: 50, mobile: true}));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.setDeviceDimensions());\n    expectType<Awaitable<FileUploadPage, { [metricName: string]: number }>>(fileUploadPage.getPerformanceMetrics());\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.enablePerformanceMetrics(true));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.enablePerformanceMetrics());\n    expectType<Awaitable<FileUploadPage, string>>(fileUploadPage.takeHeapSnapshot('./snap.heapsnapshot'));\n    expectType<Awaitable<FileUploadPage, string>>(fileUploadPage.takeHeapSnapshot());\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.registerBasicAuth('test-user', 'test-pass'));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.captureNetworkRequests(() => {}));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.mockNetworkResponse('https://example.com', {status: 200}));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.setNetworkConditions({offline: false, latency: 3000, download_throughput: 500 * 1024, upload_throughput: 500 * 1024}));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.captureBrowserConsoleLogs(() => {}));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.captureBrowserExceptions(() => {}));\n\n    // These should also work on sections with correct return types\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.setGeolocation({latitude: 35.689487, longitude: 139.691706, accuracy: 100}));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.setGeolocation());\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.setDeviceDimensions({width: 400, height: 600, deviceScaleFactor: 50, mobile: true}));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.setDeviceDimensions());\n    expectType<Awaitable<typeof menuSection, { [metricName: string]: number }>>(menuSection.getPerformanceMetrics());\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.enablePerformanceMetrics(true));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.enablePerformanceMetrics());\n    expectType<Awaitable<typeof menuSection, string>>(menuSection.takeHeapSnapshot('./snap.heapsnapshot'));\n    expectType<Awaitable<typeof menuSection, string>>(menuSection.takeHeapSnapshot());\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.registerBasicAuth('test-user', 'test-pass'));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.captureNetworkRequests(() => {}));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.mockNetworkResponse('https://example.com', {status: 200}));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.setNetworkConditions({offline: false, latency: 3000, download_throughput: 500 * 1024, upload_throughput: 500 * 1024}));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.captureBrowserConsoleLogs(() => {}));\n    expectType<Awaitable<typeof menuSection, null>>(menuSection.captureBrowserExceptions(() => {}));\n  });\n});\n\n/**************************\n * TESTS FOR CLIENT COMMANDS\n *************************/\ndescribe('Page Object - ClientCommands', function() {\n  it('should verify that ClientCommands-specific commands are not available on page objects', function() {\n    const fileUploadPage = browser.page.FileUpload();\n    const menuSection = fileUploadPage.section.menu;\n\n    // Test commands that are specific to ClientCommands (not in ChromiumClientCommands or SharedClientCommands)\n    // These commands are NOT available on page objects as they're not part of PageObjectClientCommands\n    // Verify they don't exist using expectError\n    expectError(fileUploadPage.closeWindow());\n    expectError(fileUploadPage.fullscreenWindow());\n    expectError(fileUploadPage.minimizeWindow());\n    expectError(fileUploadPage.openNewWindow());\n    expectError(fileUploadPage.getCurrentUrl());\n    expectError(fileUploadPage.navigateTo('https://example.com'));\n    expectError(fileUploadPage.quit());\n    expectError(fileUploadPage.waitUntil(function() { return true }));\n    expectError(fileUploadPage.switchWindow('handle'));\n    expectError(fileUploadPage.switchToWindow('handle'));\n\n    // These should also not be available on sections\n    expectError(menuSection.closeWindow());\n    expectError(menuSection.fullscreenWindow());\n    expectError(menuSection.minimizeWindow());\n    expectError(menuSection.openNewWindow());\n    expectError(menuSection.getCurrentUrl());\n    expectError(menuSection.navigateTo('https://example.com'));\n    expectError(menuSection.quit());\n    expectError(menuSection.waitUntil(function() { return true }));\n    expectError(menuSection.switchWindow('handle'));\n    expectError(menuSection.switchToWindow('handle'));\n  });\n});\n\n/**************************\n * TESTS FOR CUSTOM COMMAND CHAINING\n *************************/\ndescribe('Page Object - Custom Command Chaining', function() {\n  it('should support chaining custom commands with built-in commands on page objects', function() {\n    const fileUploadPage = browser.page.FileUpload();\n\n    // Chain built-in command -> custom command\n    expectType<NightwatchAPI>(fileUploadPage.pause(1000).uploadFile1('@fileUploadInput', 'test.txt'));\n    expectType<NightwatchAPI>(fileUploadPage.click('@submitButton').uploadFile1('@fileUploadInput', 'test.txt'));\n    expectType<NightwatchAPI>(fileUploadPage.setValue('@fileUploadInput', 'value').uploadFile1('@fileUploadInput', 'test.txt'));\n\n    // Chain custom command -> built-in command\n    // uploadFile1 returns NightwatchAPI, then these commands return Awaitable<NightwatchAPI, ...>\n    expectType<Awaitable<NightwatchAPI, undefined>>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').pause(1000));\n    expectType<Awaitable<NightwatchAPI, null>>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').click('@submitButton'));\n    expectType<Awaitable<NightwatchAPI, string>>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').getTitle());\n\n    // Chain multiple custom commands (uploadFile1 returns NightwatchAPI)\n    expectType<NightwatchAPI>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').uploadFile1('@fileUploadInput', 'test2.txt'));\n    // When chained with pause, pause returns Awaitable<NightwatchAPI, undefined>\n    expectType<Awaitable<NightwatchAPI, undefined>>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').uploadFile1('@fileUploadInput', 'test2.txt').pause(1000));\n\n    // Chain multiple custom commands (uploadFile3 returns 'this', preserves page object type)\n    // uploadFile3 returns FileUploadPage, so chaining multiple returns FileUploadPage\n    expectType<FileUploadPage>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt'));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.uploadFile4('@fileUploadInput', 'test.txt'));\n    expectType<FileUploadPage>(fileUploadPage.uploadFile4('@fileUploadInput', 'test.txt').uploadFile3('@fileUploadInput', 'test2.txt'));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').uploadFile4('@fileUploadInput', 'test2.txt'));\n    // When chained with pause, pause returns Awaitable\n    expectType<Awaitable<FileUploadPage, undefined>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').uploadFile3('@fileUploadInput', 'test2.txt').pause(1000));\n\n    // Chain custom command that returns 'this' (allows chaining back to page object)\n    // uploadFile3 returns FileUploadPage, then pause returns Awaitable<FileUploadPage, undefined>\n    expectType<Awaitable<FileUploadPage, undefined>>(fileUploadPage.pause(1000).uploadFile3('@fileUploadInput', 'test.txt').pause(1000));\n    expectType<Awaitable<FileUploadPage, undefined>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').pause(1000));\n    // click returns Awaitable<FileUploadPage, null>\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').click('@submitButton'));\n    expectType<Awaitable<FileUploadPage, string>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').getTitle());\n\n    // Chain custom command with Awaitable return type -> built-in command\n    expectType<Awaitable<NightwatchAPI, null>>(fileUploadPage.uploadFile2('@fileUploadInput', 'test.txt').click('@submitButton'));\n\n    // Chain built-in command -> custom command with Awaitable return type\n    expectType<Awaitable<NightwatchAPI, null>>(fileUploadPage.pause(1000).uploadFile2('@fileUploadInput', 'test.txt'));\n    expectType<Awaitable<NightwatchAPI, null>>(fileUploadPage.click('@submitButton').uploadFile2('@fileUploadInput', 'test.txt'));\n\n    // Chain custom command -> SharedClientCommands (uploadFile1 returns NightwatchAPI)\n    // These commands return Awaitable<NightwatchAPI, ...>\n    expectType<Awaitable<NightwatchAPI, undefined>>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').pause(1000));\n    expectType<Awaitable<NightwatchAPI, undefined>>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').debug());\n    expectType<Awaitable<NightwatchAPI, string>>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').getTitle());\n    expectType<Awaitable<NightwatchAPI, string>>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').saveScreenshot('test.png'));\n\n    // Chain custom command -> SharedClientCommands (uploadFile3 returns 'this', preserves page object type)\n    // uploadFile3 returns FileUploadPage, then these commands return Awaitable<FileUploadPage, ...>\n    expectType<Awaitable<FileUploadPage, undefined>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').pause(1000));\n    expectType<Awaitable<FileUploadPage, undefined>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').debug());\n    expectType<Awaitable<FileUploadPage, string>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').getTitle());\n    expectType<Awaitable<FileUploadPage, string>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').saveScreenshot('test.png'));\n\n    // Chain SharedClientCommands -> custom command (uploadFile1 returns NightwatchAPI)\n    expectType<NightwatchAPI>(fileUploadPage.pause(1000).uploadFile1('@fileUploadInput', 'test.txt'));\n    expectType<NightwatchAPI>(fileUploadPage.debug().uploadFile1('@fileUploadInput', 'test.txt'));\n    expectType<NightwatchAPI>(fileUploadPage.getTitle().uploadFile1('@fileUploadInput', 'test.txt'));\n\n    // Chain SharedClientCommands -> custom command (uploadFile3 returns 'this', preserves page object type)\n    // Note: When chaining from Awaitable, TypeScript may not properly resolve 'this' type\n    // These tests verify that uploadFile3 can be called, but type resolution may be limited\n    fileUploadPage.pause(1000).uploadFile3('@fileUploadInput', 'test.txt');\n    fileUploadPage.debug().uploadFile3('@fileUploadInput', 'test.txt');\n    fileUploadPage.getTitle().uploadFile3('@fileUploadInput', 'test.txt');\n\n    // Chain custom command -> ChromiumClientCommands (uploadFile1 returns NightwatchAPI)\n    // setGeolocation returns Awaitable<NightwatchAPI, null>\n    expectType<Awaitable<NightwatchAPI, null>>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').setGeolocation({ latitude: 35.689487, longitude: 139.691706 }));\n    expectType<Awaitable<NightwatchAPI, null>>(fileUploadPage.uploadFile1('@fileUploadInput', 'test.txt').setDeviceDimensions({ width: 400, height: 600 }));\n\n    // Chain custom command -> ChromiumClientCommands (uploadFile3 returns 'this', preserves page object type)\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').setGeolocation({ latitude: 35.689487, longitude: 139.691706 }));\n    expectType<Awaitable<FileUploadPage, null>>(fileUploadPage.uploadFile3('@fileUploadInput', 'test.txt').setDeviceDimensions({ width: 400, height: 600 }));\n\n    // Chain ChromiumClientCommands -> custom command (uploadFile1 returns NightwatchAPI)\n    expectType<NightwatchAPI>(fileUploadPage.setGeolocation({latitude: 35.689487, longitude: 139.691706}).uploadFile1('@fileUploadInput', 'test.txt'));\n    expectType<NightwatchAPI>(fileUploadPage.setDeviceDimensions({width: 400, height: 600}).uploadFile1('@fileUploadInput', 'test.txt'));\n\n    // Chain ChromiumClientCommands -> custom command (uploadFile3 returns 'this', preserves page object type)\n    // Note: When chaining from Awaitable, TypeScript may not properly resolve 'this' type\n    // These tests verify that uploadFile3 can be called, but type resolution may be limited\n    fileUploadPage.setGeolocation({latitude: 35.689487, longitude: 139.691706}).uploadFile3('@fileUploadInput', 'test.txt');\n    fileUploadPage.setDeviceDimensions({width: 400, height: 600}).uploadFile3('@fileUploadInput', 'test.txt');\n  });\n\n});\n"
  },
  {
    "path": "types/tests/programmaticApi.test-d.ts",
    "content": "// New Programmatic APi\nimport { expectType, expectError, expectAssignable } from 'tsd';\nimport Nightwatch, { NightwatchAPI, NightwatchClient, NightwatchProgrammaticAPIClient } from '..';\n\nconst client = Nightwatch.createClient({\n  browserName: 'firefox',\n  headless: true,\n});\nNightwatch.createClient();\nNightwatch.createClient({});\n\nexpectType<NightwatchProgrammaticAPIClient>(client);\n\n// test methods/properties exported on Nightwatch\nnew Nightwatch.by('css selector', 'hello');\nnew Nightwatch.Capabilities();\nexpectType<NightwatchAPI>(Nightwatch.browser);\nexpectType<NightwatchAPI>(Nightwatch.app);\nexpectAssignable<string>(Nightwatch.Key.NULL);\nexpectError(Nightwatch.launchBrowser());\n// @ts-expect-error\nNightwatch.updateCapabilities({});\n\n// test internal methods exported on Nightwatch\nconst initClient = Nightwatch.initClient();\nexpectType<typeof Nightwatch>(initClient);\n\n// test Nightwatch Programmatic API\nclient.updateCapabilities({\n  testCapability: 'one, two, three',\n});\nclient.updateCapabilities(function() { return {}; });\n\nasync () => {\n  const browser = await client.launchBrowser();\n  expectType<NightwatchAPI>(browser);\n\n  expectType<NightwatchClient>(client.nightwatch_client);\n};\n"
  },
  {
    "path": "types/tests/tsconfig.json",
    "content": "{\n    \"extends\": \"../../tsconfig\",\n    \"include\": [\".\"]\n}\n"
  },
  {
    "path": "types/tests/webElement.test-d.ts",
    "content": "import {expectAssignable, expectError, expectType} from \"tsd\";\nimport { Element, ElementAssertions, ElementValue, Elements, ScopedElement, ScopedElementRect, ValueAssertions } from \"..\";\nimport { WebElement, WebElementPromise } from \"selenium-webdriver\";\n\ndescribe('new element() api', function () {\n  test('test element()', async function () {\n    const elem = browser.element('selector');\n    expectType<ScopedElement>(elem);\n    expectType<WebElement>(await elem);\n\n    // accepts WebElement\n    expectType<ScopedElement>(browser.element(await elem));\n\n    // accepts By selector\n    expectType<ScopedElement>(browser.element(by.xpath('//tagname')));\n\n    // accepts RelativeBy selector\n    expectType<ScopedElement>(browser.element(locateWith(by.css('selector')).above(await elem)));\n\n    // accepts ElementProperties\n    expectType<ScopedElement>(browser.element({selector: 'selector', locateStrategy: 'css selector', abortOnFailure: false}));\n\n    // accepts ElementProperties with Appium-specific locate strategies\n    expectType<ScopedElement>(browser.element({selector: 'selector', locateStrategy: '-android uiautomator', abortOnFailure: false}));\n\n    // accepts Element (ScopedElement is also assignable to Element)\n    expectType<ScopedElement>(browser.element(elem));\n\n    // accepts WebElementPromise\n    expectType<ScopedElement>(browser.element(elem.webElement));\n\n    // accepts Promise<WebElement>\n    expectType<ScopedElement>(browser.element(Promise.resolve(await elem)));\n\n    // backward compatibility\n    expectType<ScopedElement>(browser.element('css selector', 'selector', function (result) {\n      expectType<never>(result);\n    }));\n  });\n\n  test('test element.methodName()', async function () {\n    const elementActive = browser.element.findActive();\n    expectType<ScopedElement>(elementActive);\n    expectType<WebElement>(await elementActive);\n\n    const elementFind = browser.element.find('selector');\n    expectType<ScopedElement>(elementFind);\n    expectType<WebElement>(await elementFind);\n\n    expectType<ScopedElement>(browser.element.get('selector'));\n    expectType<ScopedElement>(browser.element.findElement('selector'));\n\n    const elementFindByText = browser.element.findByText('some-text', {exact: true, abortOnFailure: false});\n    expectType<ScopedElement>(elementFindByText);\n\n    const elementFindByRole = browser.element.findByRole('heading', {level: 2, expanded: true, retryInterval: 100});\n    expectType<ScopedElement>(elementFindByRole);\n    browser.element.findByRole('button', {current: false, expanded: true, index: 2});\n    expectError(browser.element.findByRole('button', {level: 2, expanded: true, retryInterval: 100}));\n\n    const elementFindByPlaceholderText = browser.element.findByPlaceholderText('some-text', {exact: true, abortOnFailure: false});\n    expectType<ScopedElement>(elementFindByPlaceholderText);\n\n    const elementFindByLabelText = browser.element.findByLabelText('some-text', {exact: true, abortOnFailure: false});\n    expectType<ScopedElement>(elementFindByLabelText);\n\n    const elementFindByAltText = browser.element.findByAltText('some-text', {exact: false, abortOnFailure: false});\n    expectType<ScopedElement>(elementFindByAltText);\n\n    // findAll\n    const elementFindAll = browser.element.findAll('selector');\n    expectType<Elements>(elementFindAll);\n    expectType<WebElement[]>(await elementFindAll);\n\n    expectType<ScopedElement>(elementFindAll.nth(2));\n    expectType<number>(await elementFindAll.count());\n\n    expectType<Elements>(browser.element.getAll('selector'));\n    expectType<Elements>(browser.element.findElements('selector'));\n\n    const elementFindAllByText = browser.element.findAllByText('some-text', {exact: true, abortOnFailure: false});\n    expectType<Elements>(elementFindAllByText);\n\n    const elementFindAllByRole = browser.element.findAllByRole('heading', {level: 2, expanded: true, retryInterval: 100});\n    expectType<Elements>(elementFindAllByRole);\n    browser.element.findAllByRole('button', {current: false, expanded: true, index: 2});\n    expectError(browser.element.findAllByRole('button', {level: 2, expanded: true, retryInterval: 100}));\n\n    const elementFindAllByPlaceholderText = browser.element.findAllByPlaceholderText('some-text', {exact: true, abortOnFailure: false});\n    expectType<Elements>(elementFindAllByPlaceholderText);\n\n    const elementFindAllByAltText = browser.element.findAllByAltText('some-text', {exact: false, abortOnFailure: false});\n    expectType<Elements>(elementFindAllByAltText);\n  });\n\n  test('test ScopedElement has Element class properties', async function () {\n    const elem = browser.element('selector');\n    expectType<ScopedElement>(elem);\n    expectAssignable<Element>(elem);\n    expectAssignable<WebElement>(await elem);\n\n    expectType<string | undefined>(elem.selector);\n    expectType<number>(elem.index);\n    expectType<string | null>(elem.resolvedElement);\n  });\n\n  test('test properties/methods in ScopedElement', async function () {\n    const elem = browser.element('selector');\n    expectType<ScopedElement>(elem);\n\n    expectType<WebElementPromise>(elem.webElement);\n\n    expectType<ScopedElement>(elem.find('selector'));\n    expectType<ScopedElement>(elem.get('selector'));\n    expectType<ScopedElement>(elem.findElement('selector'));\n\n    expectType<ScopedElement>(elem.findByText('some-text', {exact: true, abortOnFailure: false}));\n\n    expectType<ScopedElement>(elem.findByRole('heading', {level: 2, expanded: true, retryInterval: 100}));\n    expectType<ScopedElement>(elem.findByRole('button', {current: false, expanded: true, index: 2}));\n    expectError(elem.findByRole('button', {level: 2, expanded: true, retryInterval: 100}));\n\n    expectType<ScopedElement>(elem.findByPlaceholderText('some-text', {exact: true, abortOnFailure: false}));\n    expectType<ScopedElement>(elem.findByLabelText('some-text', {exact: true, abortOnFailure: false}));\n    expectType<ScopedElement>(elem.findByAltText('some-text', {exact: true, abortOnFailure: false}));\n\n    expectType<Elements>(elem.findAll('selector'));\n    expectType<Elements>(elem.findElements('selector'));\n    expectType<Elements>(elem.getAll('selector'));\n\n    expectType<Elements>(elem.findAllByText('some-text', {exact: true, abortOnFailure: false}));\n\n    expectType<Elements>(elem.findAllByRole('heading', {level: 2, expanded: true, retryInterval: 100}));\n    expectType<Elements>(elem.findAllByRole('button', {current: false, expanded: true, index: 2}));\n    expectError(elem.findAllByRole('button', {level: 2, expanded: true, retryInterval: 100}));\n\n    expectType<Elements>(elem.findAllByPlaceholderText('some-text', {exact: true, abortOnFailure: false}));\n    expectType<Elements>(elem.findAllByAltText('some-text', {exact: true, abortOnFailure: false}));\n\n    expectType<ScopedElement>(elem.getFirstElementChild());\n    expectType<ScopedElement>(elem.getLastElementChild());\n    expectType<ScopedElement>(elem.getNextElementSibling());\n    expectType<ScopedElement>(elem.getPreviousElementSibling());\n\n    expectType<Omit<ScopedElement, 'then'> & PromiseLike<ShadowRoot>>(elem.getShadowRoot());\n    expectType<ShadowRoot>(await elem.getShadowRoot());\n\n    expectType<ElementValue<string>>(elem.getId());\n    expectType<ElementValue<string>>(elem.getTagName());\n    expectType<ElementValue<string>>(elem.tagName());\n    expectType<ElementValue<string>>(elem.getText());\n    expectType<ElementValue<string>>(elem.text());\n\n    expectType<ElementValue<string | null>>(elem.getProperty('property-name'));\n    expectType<ElementValue<string | null>>(elem.prop('property-name'));\n    expectType<ElementValue<string | null>>(elem.property('property-name'));\n    expectType<ElementValue<string | null>>(elem.getAttribute('attrib-name'));\n    expectType<ElementValue<string | null>>(elem.attr('attrib-name'));\n    expectType<ElementValue<string | null>>(elem.attribute('attrib-name'));\n    expectType<ElementValue<string | null>>(elem.getValue());\n    expectType<ElementValue<boolean>>(elem.isEnabled());\n    expectType<ElementValue<boolean>>(elem.isPresent());\n    expectType<ElementValue<boolean>>(elem.isSelected());\n    expectType<ElementValue<boolean>>(elem.isVisible());\n    expectType<ElementValue<boolean>>(elem.isDisplayed());\n    expectType<ElementValue<boolean>>(elem.isActive());\n\n    expectType<ElementValue<ScopedElementRect>>(elem.getRect());\n    expectType<ElementValue<ScopedElementRect>>(elem.rect());\n    expectType<ElementValue<ScopedElementRect>>(elem.getSize());\n    expectType<ElementValue<ScopedElementRect>>(elem.getLocation());\n\n    expectType<ElementValue<string>>(elem.getAccessibleName());\n    expectType<ElementValue<string>>(elem.accessibleName());\n    expectType<ElementValue<string>>(elem.getComputedLabel());\n    expectType<ElementValue<string>>(elem.getAriaRole());\n    expectType<ElementValue<string>>(elem.ariaRole());\n    expectType<ElementValue<string>>(elem.getComputedRole());\n    expectType<ElementValue<string>>(elem.getCssProperty('height'));\n    expectType<ElementValue<string>>(elem.css('height'));\n    expectType<ElementValue<string>>(elem.getCssValue('height'));\n    expectType<ElementValue<string>>(elem.takeScreenshot());\n\n    expectType<Promise<WebElement>>(elem.click());\n    expectType<Promise<WebElement>>(elem.clear());\n    expectType<Promise<WebElement>>(elem.check());\n    expectType<Promise<WebElement>>(elem.uncheck());\n    expectType<Promise<WebElement>>(elem.sendKeys('something', 1));\n    expectType<Promise<WebElement>>(elem.update('something', 1));\n    expectType<Promise<WebElement>>(elem.setValue('something', 1));\n    expectType<Promise<WebElement>>(elem.submit());\n    expectType<Promise<WebElement>>(elem.setProperty('type', 'text'));\n    expectType<Promise<WebElement>>(elem.setAttribute('role', 'button'));\n    expectType<Promise<WebElement>>(elem.dragAndDrop({x: 150, y: 500}));\n    expectType<Promise<WebElement>>(elem.dragAndDrop(elem.webElement));\n    expectType<Promise<WebElement>>(elem.moveTo(100, 100));\n    expectType<Promise<WebElement>>(elem.clickAndHold());\n    expectType<Promise<WebElement>>(elem.doubleClick());\n    expectType<Promise<WebElement>>(elem.rightClick());\n    expectType<Promise<WebElement>>(elem.waitUntil('visible', {timeout: 5000}));\n  });\n\n  test('test element assertions', async function () {\n    const elem = browser.element('selector');\n    expectType<ScopedElement>(elem);\n    expectType<ElementAssertions>(elem.assert)\n    expectType<ElementAssertions>(elem.assert.not);\n\n    expectType<Promise<WebElement>>(elem.assert.enabled('some message'));\n    expectType<WebElement>(await elem.assert.not.enabled());\n\n    expectType<Promise<WebElement>>(elem.assert.not.present());\n    expectType<WebElement>(await elem.assert.selected('some message'));\n\n    expectType<Promise<WebElement>>(elem.assert.not.selected('some message'));\n    expectType<WebElement>(await elem.assert.selected());\n\n    expectType<Promise<WebElement>>(elem.assert.visible());\n    expectType<WebElement>(await elem.assert.not.visible('some message'));\n\n    expectType<Promise<WebElement>>(elem.assert.not.hasClass('some-class'));\n    expectType<WebElement>(await elem.assert.hasClass('some-class', 'some message'));\n\n    expectType<Promise<WebElement>>(elem.assert.hasAttribute('some-attribute', 'some message'));\n    expectType<WebElement>(await elem.assert.not.hasAttribute('some-attribute'));\n\n    expectType<Promise<WebElement>>(elem.assert.hasDescendants());\n    expectType<WebElement>(await elem.assert.not.hasDescendants('some message'));\n  });\n\n  test('test ElementValue methods/properties', async function () {\n    const elem = browser.element('selector');\n    expectType<ScopedElement>(elem);\n\n    const elemId = elem.getId();\n    expectType<ElementValue<string>>(elemId);\n    expectType<string>(await elemId);\n\n    expectType<Promise<string>>(elemId.value);\n    expectType<string>(await elemId.value);\n\n    expectType<ValueAssertions<string>>(elemId.assert);\n    expectType<Promise<string>>(elemId.assert.equals('elem-id'));\n  });\n\n  test('test ValueAssertions methods/properties', async function () {\n    const elem = browser.element('selector');\n    expectType<ScopedElement>(elem);\n\n    const elemId = elem.getId();\n    expectType<ValueAssertions<string>>(elemId.assert);\n    expectType<ValueAssertions<string>>(elemId.assert.not);\n\n    expectType<Promise<string>>(elemId.assert.equals('some text'));\n    expectType<string>(await elemId.assert.not.equals('some text', 'some message'));\n\n    expectType<Promise<string>>(elemId.assert.not.contains('text', 'some message'));\n    expectType<string>(await elemId.assert.contains('some'));\n\n    expectType<Promise<string>>(elemId.assert.matches(/^some text/, 'some message'));\n    expectType<string>(await elemId.assert.not.matches(/some t[a-z]{3}$/));\n  });\n});\n"
  },
  {
    "path": "types/tests/webdriverProtocolCommands.test-d.ts",
    "content": "import { expectError, expectType } from 'tsd';\nimport {\n  NightwatchSizeAndPosition,\n  Cookie,\n  JSON_WEB_OBJECT,\n  NightwatchLogEntry,\n  WindowPosition,\n  WindowSizeAndPosition,\n  NightwatchLogTypes,\n  ElementResult,\n  NightwatchCallbackResult,\n  NightwatchAPI,\n} from '..';\nimport { WebElement } from 'selenium-webdriver';\n\n//\n// .elementIdAttribute\n//\ndescribe('elementIdAttribute command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdAttribute(webElement.getId(), 'title', function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<string | null>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdAttribute(webElement.getId(), 'title');\n    expectType<string | null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdCssProperty\n//\ndescribe('elementIdCssProperty command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdCssProperty(webElement.getId(), 'background-color', function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<string>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdCssProperty(webElement.getId(), 'background-color');\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdDisplayed\n//\ndescribe('elementIdDisplayed command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdDisplayed(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<boolean>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdDisplayed(webElement.getId());\n    expectType<boolean>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdEnabled\n//\ndescribe('elementIdEnabled command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdEnabled(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<boolean>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdEnabled(webElement.getId());\n    expectType<boolean>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdName\n//\ndescribe('elementIdName command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdName(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<string>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdName(webElement.getId());\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdSelected\n//\ndescribe('elementIdSelected command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdSelected(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<boolean>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdSelected(webElement.getId());\n    expectType<boolean>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .submit\n//\ndescribe('submit command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.submit(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.submit(webElement.getId());\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdSize\n//\ndescribe('elementIdSize command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdSize(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<NightwatchSizeAndPosition>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdSize(webElement.getId());\n    expectType<NightwatchSizeAndPosition>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdText\n//\ndescribe('elementIdText command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdText(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<string>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdText(webElement.getId());\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdClear\n//\ndescribe('elementIdClear command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdClear(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdClear(webElement.getId());\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdClick\n//\ndescribe('elementIdClick command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdClick(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdClick(webElement.getId());\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdValue\n//\ndescribe('elementIdValue command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdValue(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<string>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdValue(webElement.getId());\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdLocation\n//\ndescribe('elementIdLocation command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdLocation(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<NightwatchSizeAndPosition>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdLocation(webElement.getId());\n    expectType<NightwatchSizeAndPosition>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .source\n//\ndescribe('source command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.source(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.source();\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .doubleClick\n//\ndescribe('doubleClick command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.doubleClick('input[type=text]', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.doubleClick('input[type=text]');\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .clickAndHold\n//\ndescribe('clickAndHold command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.clickAndHold('input[type=text]', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.clickAndHold('input[type=text]');\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .moveTo\n//\ndescribe('moveTo command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.moveTo(null, 100, 100, function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.moveTo(100, 100);\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .rightClick\n//\ndescribe('rightClick command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.rightClick('input[type=text]', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.rightClick('input[type=text]');\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .acceptAlert\n//\ndescribe('acceptAlert command demo', function () {\n  before((browser) => browser.url('https://nightwatchjs.org/__e2e/window/alerts.html/'));\n\n  test('demo test', function (browser) {\n    browser.click({selector: '#show-alert', locateStrategy: 'accessibility id'}).acceptAlert(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.click('#show-alert').acceptAlert();\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .dismissAlert\n//\ndescribe('dismissAlert command demo', function () {\n  before((browser) => browser.url('https://nightwatchjs.org/__e2e/window/alerts.html/'));\n\n  test('demo test', function (browser) {\n    browser.click('#show-alert').dismissAlert(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.click('#show-alert').dismissAlert();\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .getAlertText\n//\ndescribe('getAlertText command demo', function () {\n  before((browser) => browser.url('https://nightwatchjs.org/__e2e/window/alerts.html/'));\n\n  test('demo test', function (browser) {\n    browser.click('#show-alert').getAlertText(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.click('#show-alert').getAlertText();\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .setAlertText\n//\ndescribe('setAlertText command demo', function () {\n  before((browser) => browser.url('https://nightwatchjs.org/__e2e/window/alerts.html/'));\n\n  test('demo test', function (browser) {\n    browser.click('#show-alert').setAlertText('nightwatch', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.click('#show-alert').setAlertText('nightwatch');\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .registerBasicAuth\n//\ndescribe('registerBasicAuth command demo', function () {\n  test('demo test', function (browser) {\n    browser.registerBasicAuth('test', 'test', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.registerBasicAuth('test', 'test');\n    expectType<null>(result);\n  });\n});\n\n//\n// .cookie\n//\ndescribe('cookie command demo', function () {\n  test('demo test', function (browser) {\n    browser.cookie('GET', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<Cookie[] | null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.cookie('DELETE', 'sample');\n    expectType<null>(result);\n  });\n});\n\n//\n// .session\n//\ndescribe('session command demo', function () {\n  test('demo test', function (browser) {\n    browser.session(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<Record<string, any>>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.session();\n    expectType<Record<string, any>>(result);\n  });\n});\n\n//\n// .sessionLog\n//\ndescribe('sessionLog command demo', function () {\n  test('demo test', function (browser) {\n    browser.sessionLog('driver', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<NightwatchLogEntry[]>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.sessionLog('driver');\n    expectType<NightwatchLogEntry[]>(result);\n  });\n});\n\n//\n// .sessionLogTypes\n//\ndescribe('sessionLogTypes command demo', function () {\n  test('demo test', function (browser) {\n    browser.sessionLogTypes(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<NightwatchLogTypes[]>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.sessionLogTypes();\n    expectType<NightwatchLogTypes[]>(result);\n  });\n});\n\n//\n// .url\n//\ndescribe('url command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.url(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.url();\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .title\n//\ndescribe('title command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.title(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.title();\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .back\n//\ndescribe('back command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.back(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.back();\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .forward\n//\ndescribe('forward command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.forward(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.forward();\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .refresh\n//\ndescribe('refresh command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.refresh(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.refresh();\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .windowHandle\n//\ndescribe('windowHandle command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.windowHandle(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.windowHandle();\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .windowMaximize\n//\ndescribe('windowMaximize command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.windowMaximize('current', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.windowMaximize();\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .windowPosition\n//\ndescribe('windowPosition command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.windowPosition('current', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<WindowPosition>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.windowPosition('current', 22, 47);\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .windowSize\n//\ndescribe('windowSize command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.windowSize('current', function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<WindowSizeAndPosition>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.windowSize('current', 746, 1200);\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .windowRect\n//\ndescribe('windowRect command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.windowRect({ width: 100, height: 100 }, function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.windowRect(null);\n    expectType<WindowSizeAndPosition>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .frame\n//\ndescribe('frame command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.frame(null, function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.frame(null);\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .frameParent\n//\ndescribe('frameParent command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.frame(null).frameParent(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<null>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.frame(null).frameParent();\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdElement\n//\ndescribe('elementIdElement command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdElement(webElement.getId(), 'css selector', 'body', function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<ElementResult | []>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdElement(webElement.getId(), 'css selector', 'body');\n    expectType<ElementResult | []>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementIdDoubleClick\n//\ndescribe('elementIdDoubleClick command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.findElement('input[type=text]', function (result) {\n      const webElement = result.value as JSON_WEB_OBJECT;\n      browser.elementIdDoubleClick(webElement.getId(), function (result) {\n        expectType<NightwatchAPI>(this);\n        expectType<NightwatchCallbackResult<null>>(result);\n      });\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const webElement = await browser.findElement('input[type=text]');\n    const result = await browser.elementIdDoubleClick(webElement.getId());\n    expectType<null>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .elementActive\n//\ndescribe('elementActive command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', function (browser) {\n    browser.elementActive(function (result) {\n      expectType<NightwatchAPI>(this);\n      expectType<NightwatchCallbackResult<string>>(result);\n    });\n  });\n\n  test('async demo test', async function (browser) {\n    const result = await browser.elementActive();\n    expectType<string>(result);\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .element\n//\ndescribe('element command demo', function() {\n    before(browser => browser.url('https://www.google.com/'));\n\n    test('demo test', function() {\n      browser.element('css selector', 'body');\n    });\n\n    test('async demo test', async function() {\n      const result = await browser.element('css selector', 'body');\n      expectType<WebElement>(result);\n    });\n\n    after(browser => browser.end());\n});\n\n//\n// .execute\n//\ndescribe('execute command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', async function (browser) {\n    const result1 = await browser.execute(function () {});\n    expectType<null>(result1);\n\n    const result2 = await browser.execute(function () {\n      return 'nightwatch';\n    });\n    expectType<string>(result2);\n\n    expectError(await browser.execute(function (arg1: string) {\n      return 'nightwatch';\n    }))\n\n    await browser.execute(\n      function (arg1: string) {\n        return 'nightwatch';\n      },\n      ['js']\n    );\n\n    expectError(await browser.execute(\n      function (arg1: string) {\n        return 'nightwatch';\n      },\n      [123]\n    ))\n\n    expectError(await browser.execute(\n      function (arg1: string) {\n        return 'nightwatch';\n      },\n      ['js', 123]\n    ))\n\n    const result3 = await browser.execute('something');\n    expectType<unknown>(result3)\n    \n    const result4 = await browser.execute('something', ['something', 5]);\n    expectType<unknown>(result4)\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .executeScript\n//\ndescribe('executeScript command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', async function (browser) {\n    const result1 = await browser.executeScript(function () {});\n    expectType<null>(result1);\n\n    const result2 = await browser.executeScript(function () {\n      return 'nightwatch';\n    });\n    expectType<string>(result2);\n\n    const result3 = await browser.executeScript(\n      function (arg1) {\n        return arg1;\n      },\n      ['nightwatch']\n    );\n    expectType<string>(result3);\n\n    expectError(await browser.executeScript(function (arg1: string) {\n      return 'nightwatch';\n    }))\n\n    await browser.executeScript(\n      function (arg1: string) {\n        return 'nightwatch';\n      },\n      ['js']\n    );\n\n    expectError(await browser.executeScript(\n      function (arg1: string) {\n        return 'nightwatch';\n      },\n      [123]\n    ))\n\n    expectError(await browser.executeScript(\n      function (arg1: string) {\n        return 'nightwatch';\n      },\n      ['js', 123]\n    ))\n\n    const result4 = await browser.execute('something');\n    expectType<unknown>(result4)\n\n    const result5 = await browser.execute('something', ['something', 5]);\n    expectType<unknown>(result5)\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .executeAsyncScript\n//\ndescribe('executeAsyncScript command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', async function (browser) {\n    const result = await browser.executeAsyncScript(\n      function (arg1: string, arg2: number, done: (arg: string) => void) {\n        return 'nightwatch';\n      },\n      ['js', 1]\n    );\n    expectType<string>(result);\n\n    const result1 = await browser.executeAsyncScript(function (done: () => void) {\n      return 'nightwatch';\n    });\n    expectType<unknown>(result1)\n\n    const result2 = await browser.executeAsyncScript(function () {});\n    expectType<unknown>(result2)\n\n    const result3 = await browser.executeAsyncScript(\n      function (arg1: number, done) {\n        return 'nightwatch';\n      },\n      [2]\n    );\n    expectType<unknown>(result3)\n\n    expectError(await browser.executeAsyncScript(function (arg1: string) {\n      return 'nightwatch';\n    }))\n\n    expectError(await browser.executeAsyncScript(\n      function (arg1: string, done: (result: string) => void) {\n        return 'nightwatch';\n      },\n      [123]\n    ))\n\n    expectError(await browser.executeAsyncScript(\n      function (arg1: string, done) {\n        return 'nightwatch';\n      },\n      ['js', 123]\n    ))\n\n    const result4 = await browser.executeAsyncScript('something');\n    expectType<unknown>(result4)\n\n    const result5 = await browser.executeAsyncScript('something', ['something', 5]);\n    expectType<unknown>(result5)\n  });\n\n  after((browser) => browser.end());\n});\n\n//\n// .executeAsync\n//\ndescribe('executeAsync command demo', function () {\n  before((browser) => browser.url('https://www.google.com/'));\n\n  test('demo test', async function (browser) {\n    const result = await browser.executeAsync(\n      function (arg1: string, arg2: number, done: (arg: string) => void) {\n        return 'nightwatch';\n      },\n      ['js', 1]\n    );\n    expectType<string>(result);\n\n    const result1 = await browser.executeAsync(function (done: () => void) {\n      return 'nightwatch';\n    });\n    expectType<unknown>(result1)\n\n    const result2 = await browser.executeAsync(function () {});\n    expectType<unknown>(result2)\n\n    const result3 = await browser.executeAsync(\n      function (arg1: number, done) {\n        return 'nightwatch';\n      },\n      [2]\n    );\n    expectType<unknown>(result3)\n\n    expectError(await browser.executeAsync(function (arg1: string) {\n      return 'nightwatch';\n    }))\n\n    expectError(await browser.executeAsync(\n      function (arg1: string, done: (result: string) => void) {\n        return 'nightwatch';\n      },\n      [123]\n    ))\n\n    expectError(await browser.executeAsync(\n      function (arg1: string, done) {\n        return 'nightwatch';\n      },\n      ['js', 123]\n    ))\n\n    const result4 = await browser.executeAsync('something');\n    expectType<unknown>(result4)\n\n    const result5 = await browser.executeAsync('something', ['something', 5]);\n    expectType<unknown>(result5)\n  });\n\n  after((browser) => browser.end());\n});\n"
  },
  {
    "path": "types/utils.d.ts",
    "content": "/**\n * Merge Objects Array\n *\n * @example\n * // if array\n * [{ a: {}, b: {} }, { c: {} }] => { a: {}, b: {}, c: {} }\n *\n * // if object\n * {} => {}\n */\nexport type MergeObjectsArray<T> = T extends Array<unknown>\n  ? {\n      [K in keyof T[number]]: T[number][K];\n    }\n  : T;\n\n/**\n * If the first type is of type `unknown`, change it to the second type.\n */\nexport type IfUnknown<T, X> = unknown extends T ? X : T;\n\n\n"
  },
  {
    "path": "types/web-element.d.ts",
    "content": "import {\n  By,\n  RelativeBy,\n  WebElement,\n  WebElementPromise\n} from 'selenium-webdriver';\n\nimport {ElementProperties} from './page-object';\nimport {Element, LocateStrategy, NightwatchClient} from './index';\n\nexport interface ScopedElement extends Element, PromiseLike<WebElement> {\n  assert: ElementAssertions;\n\n  webElement: WebElementPromise;\n\n  find(selector: ScopedElementSelector): ScopedElement;\n  get(selector: ScopedElementSelector): ScopedElement;\n  findElement(selector: ScopedElementSelector): ScopedElement;\n\n  findByText(\n    text: string,\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly exact?: boolean;\n    }\n  ): ScopedElement;\n\n  findByRole(\n    role: 'heading',\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly level?: number;\n      readonly checked?: boolean;\n      readonly current?: boolean | string;\n      readonly pressed?: boolean;\n      readonly expanded?: boolean;\n      readonly selected?: boolean;\n    }\n  ): ScopedElement;\n\n  findByRole(\n    role: string,\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly current?: boolean | string;\n      readonly checked?: boolean;\n      readonly pressed?: boolean;\n      readonly selected?: boolean;\n      readonly expanded?: boolean;\n    }\n  ): ScopedElement;\n\n  findByPlaceholderText(\n    text: string,\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly exact?: boolean;\n    }\n  ): ScopedElement;\n\n  findByLabelText(\n    text: string,\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly exact?: boolean;\n    }\n  ): ScopedElement;\n\n  findByAltText(\n    text: string,\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly exact?: boolean;\n    }\n  ): ScopedElement;\n\n  findAll(selector: ScopedSelector | Promise<ScopedSelector>): Elements;\n  getAll(selector: ScopedSelector | Promise<ScopedSelector>): Elements;\n  findElements(selector: ScopedSelector | Promise<ScopedSelector>): Elements;\n\n  findAllByText(\n    text: string,\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly exact?: boolean;\n    }\n  ): Elements;\n\n  findAllByRole(\n    role: 'heading',\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly level?: number;\n      readonly checked?: boolean;\n      readonly current?: boolean | string;\n      readonly pressed?: boolean;\n      readonly expanded?: boolean;\n      readonly selected?: boolean;\n    }\n  ): Elements;\n\n  findAllByRole(\n    role: string,\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly current?: boolean | string;\n      readonly checked?: boolean;\n      readonly pressed?: boolean;\n      readonly selected?: boolean;\n      readonly expanded?: boolean;\n    }\n  ): Elements;\n\n  getAllByRole(\n    role: string,\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly current?: boolean | string;\n      readonly checked?: boolean;\n      readonly pressed?: boolean;\n      readonly selected?: boolean;\n      readonly expanded?: boolean;\n    }\n  ): Elements;\n\n  findAllByPlaceholderText(\n    text: string,\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly exact?: boolean;\n    }\n  ): Elements;\n\n  findAllByAltText(\n    text: string,\n    options?: Omit<ScopedSelectorObject, 'selector'> & {\n      readonly exact?: boolean;\n    }\n  ): Elements;\n\n  getFirstElementChild(): ScopedElement;\n\n  getLastElementChild(): ScopedElement;\n\n  getNextElementSibling(): ScopedElement;\n\n  getPreviousElementSibling(): ScopedElement;\n\n  getShadowRoot(): Omit<ScopedElement, 'then'> & PromiseLike<ShadowRoot>;\n\n  getId(): ElementValue<string>;\n\n  getRect(): ElementValue<ScopedElementRect>;\n\n  rect(): ElementValue<ScopedElementRect>;\n\n  getSize(): ElementValue<ScopedElementRect>;\n\n  getLocation(): ElementValue<ScopedElementRect>;\n\n  getTagName(): ElementValue<string>;\n  tagName(): ElementValue<string>;\n\n  getText(): ElementValue<string>;\n  text(): ElementValue<string>;\n\n  click(): Promise<WebElement>;\n\n  clear(): Promise<WebElement>;\n\n  check(): Promise<WebElement>;\n  uncheck(): Promise<WebElement>;\n\n  sendKeys<E extends readonly unknown[]>(...keys: E): Promise<WebElement>;\n\n  submit(): Promise<WebElement>;\n\n  getProperty(name: string): ElementValue<string | null>;\n  prop(name: string): ElementValue<string | null>;\n  property(name: string): ElementValue<string | null>;\n\n  setProperty(name: string, value: unknown): Promise<WebElement>;\n\n  getAttribute(name: string): ElementValue<string | null>;\n  attr(name: string): ElementValue<string | null>;\n  attribute(name: string): ElementValue<string | null>;\n\n  setAttribute(name: string, value: string | null): Promise<WebElement>;\n\n  takeScreenshot(): ElementValue<string>;\n\n  dragAndDrop(destination: DragAndDropDestination): Promise<WebElement>;\n\n  moveTo(x?: number, y?: number): Promise<WebElement>;\n\n  update<E extends readonly unknown[]>(...keys: E): Promise<WebElement>;\n\n  upload(file: string): Promise<WebElement>;\n\n  getAccessibleName(): ElementValue<string>;\n  accessibleName(): ElementValue<string>;\n  getComputedLabel(): ElementValue<string>;\n\n  getAriaRole(): ElementValue<string>;\n  ariaRole(): ElementValue<string>;\n  getComputedRole(): ElementValue<string>;\n\n  getCssProperty(name: string): ElementValue<string>;\n  css(name: string): ElementValue<string>;\n  getCssValue(name: string): ElementValue<string>;\n\n  getValue(): ElementValue<string | null>;\n\n  setValue<E extends readonly unknown[]>(...keys: E): Promise<WebElement>;\n\n  clickAndHold(): Promise<WebElement>;\n\n  doubleClick(): Promise<WebElement>;\n\n  rightClick(): Promise<WebElement>;\n\n  waitUntil(signalOrOptions: WaitUntilActions | WaitUntilOptions, waitOptions?: WaitUntilOptions): Promise<WebElement>;\n\n  isEnabled(): ElementValue<boolean>;\n\n  isPresent(): ElementValue<boolean>;\n\n  isSelected(): ElementValue<boolean>;\n\n  isVisible(): ElementValue<boolean>;\n  isDisplayed(): ElementValue<boolean>;\n\n  isActive(): ElementValue<boolean>;\n}\n\ntype WaitUntilOptions = {\n  action?: WaitUntilActions;\n  timeout?: number;\n  message?: string;\n  selector?: string;\n  retryInterval?: number;\n  abortOnFailure?: boolean;\n};\n\ntype WaitUntilActions = 'selected' | 'visible' | 'disabled' | 'enabled' | 'not.selected' | 'not.visible' | 'not.enabled' | 'present' | 'not.present';\n\nexport class Elements implements PromiseLike<WebElement[]> {\n  constructor(\n    selector: ScopedElementSelector,\n    parentScopedElement: ScopedElement | null,\n    nightwatchInstance: NightwatchClient\n  );\n\n  then<R1 = WebElement[], R2 = never>(\n    onfulfilled?:\n      | ((value: WebElement[]) => R1 | PromiseLike<R1>)\n      | null\n      | undefined,\n    onrejected?: ((reason: any) => R2 | PromiseLike<R2>) | null | undefined\n  ): PromiseLike<R1 | R2>;\n\n  nth(index: number): ScopedElement;\n  count(): ElementValue<number>;\n}\n\nexport type ValueAssertionsOptions = {\n  readonly negated: boolean;\n  readonly nightwatchInstance: NightwatchClient;\n};\n\nexport class ValueAssertions<T> {\n  scopedValue: ElementValue<T>;\n\n  get not(): ValueAssertions<T>;\n\n  constructor(scopedValue: ElementValue<T>, options: ValueAssertionsOptions);\n\n  contains(expected: string, message?: string): Promise<T>;\n\n  equals(expected: T, message?: string): Promise<T>;\n\n  matches(expected: string | RegExp, message?: string): Promise<T>;\n}\n\nexport type ElementsAssertionsOptions = {\n  readonly negated: boolean;\n  readonly nightwatchInstance: NightwatchClient;\n};\n\nexport class ElementsAssertions {\n  constructor(elements: Elements, options: ElementsAssertionsOptions);\n\n  get not(): ElementsAssertions;\n\n}\n\nexport type ElementAssertionsOptions = {\n  readonly negated: boolean;\n  readonly nightwatchInstance: NightwatchClient;\n};\n\nexport class ElementAssertions {\n  constructor(element: ScopedElement, options: ElementAssertionsOptions);\n\n  get not(): ElementAssertions;\n\n  enabled(message?: string): Promise<WebElement>;\n\n  selected(message?: string): Promise<WebElement>;\n\n  visible(message?: string): Promise<WebElement>;\n\n  present(message?: string): Promise<WebElement>;\n\n  hasClass(name: string, message?: string): Promise<WebElement>;\n\n  hasAttribute(name: string, message?: string): Promise<WebElement>;\n\n  hasDescendants(message?: string): Promise<WebElement>;\n}\n\nexport class ElementValue<T> implements PromiseLike<T> {\n  value: Promise<T>;\n\n  get assert(): ValueAssertions<T>;\n\n  constructor(value: T | PromiseLike<T>, nightwatchInstance: NightwatchClient);\n\n  then<R1 = T, R2 = never>(\n    onfulfilled?: ((value: T) => R1 | PromiseLike<R1>) | null | undefined,\n    onrejected?: ((reason: any) => R2 | PromiseLike<R2>) | null | undefined\n  ): PromiseLike<R1 | R2>;\n\n  map<K>(callback: (value: T) => K | PromiseLike<K>): ElementValue<K>;\n}\n\nexport type ScopedSelectorObject = Omit<\n  ElementProperties,\n  'webElement' | 'webElementId' | 'selector'\n> & {\n  readonly selector: string | By | RelativeBy;\n};\n\ntype ScopedSelector = By | string | Element | RelativeBy | ElementProperties;\n\nexport class ElementLocator {\n  index: number;\n  timeout: number;\n  condition: By | RelativeBy;\n  retryInterval: number;\n  locateStrategy: LocateStrategy;\n  abortOnFailure: boolean;\n  suppressNotFoundErrors: boolean;\n\n  constructor(\n    selector: ScopedSelector | ElementLocator,\n    nightwatchInstance: NightwatchClient\n  );\n}\n\nexport type ScopedElementSelector =\n  | WebElement\n  | ScopedSelector\n  | WebElementPromise\n  | Promise<WebElement | ScopedSelector>;\n\nexport type ScopedElementRect = {\n  readonly x: number;\n  readonly y: number;\n  readonly width: number;\n  readonly height: number;\n};\n\nexport type DragAndDropDestination = \n  | {readonly x: number; readonly y: number;}\n  | WebElement\n\nexport interface ElementFunction\n  extends Pick<\n    ScopedElement,\n    'find' | 'get' | 'findElement' | 'findByText' | 'findByRole' | 'findByPlaceholderText' | 'findByLabelText' | 'findByAltText' |\n    'findAll' | 'getAll' | 'findElements' | 'findAllByText' | 'findAllByRole' | 'findAllByPlaceholderText' | 'findAllByAltText'\n  > {\n  (selector: ScopedElementSelector): ScopedElement;\n  (\n    using: LocateStrategy,\n    value: string,\n    callback?: (result: never) => void\n  ): ScopedElement;\n\n  findActive(): ScopedElement;\n}\n"
  }
]